¿Por qué printf muestra un 0 para el tamaño del vector cuando cout muestra el tamaño correcto?
Pregunta
No entiendo por qué obtengo 0 cuando uso printf y %d para obtener el tamaño de mi vector:
vector<long long> sieve;
int size;
...
//add stuff to vector
...
size = sieve.size();
printf("printf sieve size: %d \n", size); //prints "printf sieve size: 0"
std::cout << "cout sieve size: ";
std::cout << size;
std::cout << " \n ";
//prints "cout sieve size: 5 (or whatever the correct sieve size is)"
Si itero a través del vector a través de
if(i=0;i<sieve.size();i++)
Obtengo el número correcto de iteraciones.
¿Qué estoy haciendo mal o qué pasa con printf?size() devuelve un int ¿verdad?
Aquí está mi pequeño guión completo:
#include <iostream>
#include <vector>
#include <stack>
#include <math.h>
int main (int argc, char * const argv[]) {
unsigned long long answer = 0;
unsigned long long cur = 2;
std::vector<long long> sieve;
unsigned long long limit;
unsigned long long value;
unsigned int i;
int size;
bool isPrime;
std::cout << "Provide a value to find its largest prime factor: ";
std::cin >> value;
limit = ceil(sqrt(value));
sieve.push_back(2);
while(cur++ < limit){
isPrime = true;
sieve.begin();
for(i=0; i<sieve.size();i++){
if(!(cur % sieve[i])){
isPrime = false;
break;
}
}
if(isPrime){
if(!(value % cur)){
std::printf("Is prime factor: %d\n", cur);
sieve.push_back(cur);
answer = sieve[sieve.size() - 1];
size = sieve.size();
std::printf("current last: %d sieve size: %ld\n", answer, size);
for(i=0; i<sieve.size();i++){
std::printf("sieve iter: %d sieve val: %d\n", i, sieve[i]);
std::cout << size;
std::cout << " wtf\n";
}
}
}
}
answer = sieve[sieve.size() - 1];
size = sieve.size();
std::printf("Limit: %d Answer: %d sieve size: %ld\n", limit, answer, size);
return 0;
}
Solución
Ahora, con la fuente completa, está claro.
Usted declaró:
int size;
Luego usaste:
std::printf("current last: %d sieve size: %ld\n", answer, size);
std::printf("Limit: %d Answer: %d sieve size: %ld\n", limit, answer, size);
Si el tamaño es int, debe usar "% d " ;, no "% ld " ;. Un buen compilador te hubiera advertido sobre esto. GCC ofrece estas advertencias para su versión original:
test.cpp: In function ‘int main(int, char* const*)’:
test.cpp:17: warning: converting to ‘long long unsigned int’ from ‘double’
test.cpp:30: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:34: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:34: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘int’
test.cpp:36: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long long int’
test.cpp:45: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:45: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long long unsigned int’
test.cpp:45: warning: format ‘%ld’ expects type ‘long int’, but argument 4 has type ‘int’
Esto dice mucho.
Debe declarar el tamaño como:
std::vector<long long>::size_type size;
Entonces deberías usarlo como:
std::printf("current last: %llu sieve size: %llu\n", (unsigned long long) answer, (unsigned long long) size);
std::printf("Limit: %llu Answer: %llu sieve size: %llu\n", (unsigned long long) limit, (unsigned long long) answer, (unsigned long long) size);
Por supuesto, el uso de iostream evita estos problemas, especialmente la conversión fea en printf () para transformar el tamaño a un tipo conocido por printf.
Otros consejos
Esto es un desastre porque tienes:
unsigned long long answer = 0;
int size;
y tu llamas printf
con:
std::printf("current last: %d sieve size: %ld\n", answer, size);
Ambas cadenas de formato son incorrectas:
estas pasando
answer
aprintf
y formatearlo%d
, pero debería ser%lld
, ya que está declaradounsigned long long
.Estás pasando el tamaño con
%d
en lugar de%ld
.Desdesize
es yint
, debería ser%d
.
Cuando esos argumentos pasan a printf, imprime los primeros 32 bits de answer
Por el primero %d
y los segundos 32 bits (o más, ¡más allá del final!) de answer
Para el %ld
.Esto es no Lo que quieras.
Si compilas con -Wall
su compilador debería advertirle sobre este tipo de cosas.¡Presta mucha atención a las advertencias!
Parece loco. Debido a que el tamaño se declara como & Quot; int size & Quot ;, printf (& Quot; ...% d & Quot;) es definitivamente correcto. No puede tratarse de que size_t sea diferente de & Quot; int & Quot; en tamaño, porque declaras explícitamente " size " como int, y cout < < ... el tamaño ... funciona correctamente.
¿Has comprobado que has incluido? Puede ser que sin una declaración adecuada en su sistema printf funcione & Quot; incorrecto & Quot ;.
Tu problema es que answer
se define como un long long
y solo lo imprimes con un %d
.
printf es una función varargs y en C eso significa el compilador no lo sabe qué argumentos pasaste a la función.No puede realizar sus conversiones de tipo normales y tiene que confianza su usuario debe obtener los argumentos de formato correctos, o los argumentos no se extraerán de la pila de llamadas correctamente.
No lo hiciste bien.
tamaños de vector son size_t
, que creo que suele ser un long
...
Sin embargo, no podría decir por qué printf
no funciona.
El método size()
devuelve size_t
, que depende de su implementación de c ++. Cuando intentas printf("%d")
, le estás diciendo a la biblioteca que espere un int
, lo cual no es necesariamente el caso; luego toma un printf("%d", (int) size)
de la pila de llamadas, que solo toma los bytes de orden superior del <=>.
Lo que deberá hacer es forzar el valor de retorno <=> a un tipo de datos conocido con conversión: <=>
¿Cuál es el hardware en el que estás ejecutando?Lo más probable es que size
Es un tipo diferente de lo que piensas.Imprimir sizeof(size)
y comprobar, o probar un %ld
.Si tienes una máquina big-endian como una PPC, el tamaño es una long
, e imprimes un %d
, obtienes el final del largo con todos ceros.
actualizar
Bien, esto es lo que obtengo con una Intel Mac mini, 10.5:
$ cat trySize.C
#include <iostream>
#include <vector>
int main(){
std::cout << "sizeof(size_t): "
<< sizeof(size_t)
<< std::endl ;
std::vector<long long> sieve ;
std::cout << "sizeof(sieve.size()): "
<< sizeof(sieve.size())
<< std::endl;
printf("sizeof(sieve.size()) (printf): %d\n", sizeof(sieve.size()));
return 0;
}
$ g++ trySize.C
$ ./a.out
sizeof(size_t): 4
sizeof(sieve.size()): 4
sizeof(sieve.size()) (printf): 4
$
Probablemente deberías empezar a dividir el código en partes más pequeñas y probarlas;Hay algo raro aquí.
Esto funcionará:
std::printf("current last: %**lld** sieve size: %ld\n", answer, size);
El problema es que la respuesta es larga, larga (un entero de 64 bits) y% d espera un entero de 32 bits. Entonces el tamaño no se imprime. Deberá usar% lld.
Para obtener más información sobre cadenas de formato para printf, consulte: http://en.wikipedia.org/wiki/Printf