¿Por qué printf muestra un 0 para el tamaño del vector cuando cout muestra el tamaño correcto?

StackOverflow https://stackoverflow.com/questions/601180

  •  03-07-2019
  •  | 
  •  

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;
}
¿Fue útil?

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:

  1. estas pasando answer a printf y formatearlo %d, pero debería ser %lld, ya que está declarado unsigned long long.

  2. Estás pasando el tamaño con %d en lugar de %ld.Desde size es y int, 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.

Los

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top