perché printf mostra a 0 per il vettore di dimensione quando cout mostra la dimensione giusta?

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

  •  03-07-2019
  •  | 
  •  

Domanda

Non capisco perché ottengo 0 quando ho l'uso di printf e %d per ottenere le dimensioni del mio vettore:

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)"

Se faccio scorrere il vettore di via

if(i=0;i<sieve.size();i++) 

Ottenere il corretto numero di iterazioni.

Che cosa sto facendo di sbagliato o che cosa è in su con printf?size() restituisce un int giusto??


Ecco tutto il mio piccolo script:

#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;
}
È stato utile?

Soluzione

Ora, con la fonte completa, è chiaro.

Hai dichiarato:

int size;

Quindi hai usato:

std::printf("current last: %d sieve size: %ld\n", answer, size);
std::printf("Limit: %d Answer: %d sieve size: %ld\n", limit, answer, size);

Se size è int, dovresti usare "% d " ;, non "% ld " ;. Un buon compilatore ti avrebbe avvertito di questo. GCC fornisce questi avvisi per la tua versione originale:

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’

Questo dice molto.

Dovresti dichiarare la dimensione come:

std::vector<long long>::size_type size;

Quindi dovresti usarlo come:

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);

Ovviamente, usare iostream evita questi problemi, specialmente il brutto casting in printf () per trasformare le dimensioni in un tipo noto a printf.

Altri suggerimenti

Questo sta rovinando perché hai:

unsigned long long answer = 0;
int size;

e chiami printf con:

std::printf("current last: %d sieve size: %ld\n", answer, size);

Entrambe le stringhe di formato sono errate:

  1. Stai passando answer a %d e formattandolo %lld, ma dovrebbe essere unsigned long long, poiché è dichiarato %ld.

  2. Stai passando le dimensioni con size anziché int. Poiché -Wall è e <=>, dovrebbe essere <=>.

Quando questi argomenti vengono passati a printf, stampa i primi 32 bit di <=> per il primo <=> e i secondi 32 bit (o più, oltre la fine!) di <=> per <=> . Questo non è quello che vuoi.

Se compili con <=> il tuo compilatore dovrebbe avvisarti di questo tipo di cose. Presta molta attenzione agli avvertimenti!

Sembra pazzo. Perché size è dichiarato come & Quot; int size & Quot ;, printf (& Quot; ...% d & Quot;) è decisamente corretto. Non può essere che size_t sia diverso da & Quot; int & Quot; in termini di dimensioni, poiché si dichiara esplicitamente " size " come int e cout < < ... size ... funziona correttamente.

Hai verificato di aver incluso? È possibile che senza un'adeguata dichiarazione sul sistema printf funzioni & Quot; errato & Quot ;.

Il tuo problema è che answer è definito come long long e lo stampi solo con un %d.

printf è una funzione varargs e in C significa che il compilatore non sa quali argomenti hai passato nella funzione. Non può fare le sue normali conversioni di tipo e deve fidarsi del suo utente per ottenere correttamente gli argomenti del formato, altrimenti gli argomenti non verranno estratti correttamente dallo stack di chiamate.

Non hai capito bene.

le dimensioni dei vettori sono size_t, che credo sia generalmente un long ...

Non saprei dire perché printf non funzioni, tuttavia.

Il metodo size() restituisce size_t, che dipende dalla tua implementazione c ++. Quando provi a printf("%d"), stai dicendo alla biblioteca di aspettarsi un int, che non è necessariamente il caso; prende quindi un printf("%d", (int) size) dallo stack di chiamate, che sta prendendo solo i byte di ordine superiore del <=>.

Quello che devi fare è forzare il valore di ritorno <=> a un tipo di dati noto con casting: <=>

Che cosa è l'hardware che si sta eseguendo su?Le probabilità sono che size è un tipo diverso di quanto si pensi.Stampa sizeof(size) e di controllo, o di provare un %ld.Se si dispone di un big-endian macchina come un PPC, la dimensione è un long, e si stampa un %d, è il zeri fine del lungo.

aggiornamento

Okay, questo è quello che ottengo con un 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
$ 

Probabilmente si dovrebbe iniziare a rompere il codice in piccoli pezzi e cercando;c'è qualcosa di hinky qui.

Funzionerà:

std::printf("current last: %**lld** sieve size: %ld\n", answer, size);

Il problema è che la risposta è lunga (un numero intero a 64 bit) e% d prevede un numero intero a 32 bit. Quindi le dimensioni non vengono stampate. Dovrai usare% lld.

Per ulteriori informazioni sulle stringhe di formato per printf, consulta: http://en.wikipedia.org/wiki/Printf

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top