pourquoi printf affiche-t-il un 0 pour la taille du vecteur alors que cout affiche la taille correcte?

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

  •  03-07-2019
  •  | 
  •  

Question

Je ne comprends pas pourquoi j'obtiens 0 lorsque j'utilise printf et% d pour obtenir la taille de mon vecteur:

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 j'itère à travers le vecteur via

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

Je reçois le nombre correct d'itérations.

Qu'est-ce que je fais mal ou qu'est-ce qui se passe avec printf? size () retourne un int correct ??

Voici tout mon petit 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;
}
Était-ce utile?

La solution

Maintenant, avec la source complète, tout est clair.

Vous avez déclaré:

int size;

Ensuite, vous avez utilisé:

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 size est int, vous devez utiliser & "% d &", pas & "% ld &". Un bon compilateur vous aurait prévenu à ce sujet. GCC émet ces avertissements pour votre version d'origine:

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’

Cela en dit long.

Vous devez déclarer la taille comme suit:

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

Ensuite, vous devriez l'utiliser comme:

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

Bien sûr, l’utilisation d’iostream vous évite ces problèmes, en particulier la conversion laide dans printf () pour transformer la taille en un type connu de printf.

Autres conseils

C'est foiré parce que vous avez:

unsigned long long answer = 0;
int size;

et vous appelez printf avec:

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

Vos deux chaînes de format sont incorrectes:

  1. Vous passez answer à %d et le formatez %lld, mais ce devrait être unsigned long long, car il est déclaré %ld.

  2. Vous passez la taille avec size au lieu de int. Etant donné que -Wall est et <=>, il devrait être <=>.

Lorsque ces arguments sont passés à printf, les 32 premiers bits de <=> sont imprimés pour le premier <=> et les 32 derniers bits (ou plus, après la fin!) de <=> pour le <=> . Ce n'est pas ce que vous voulez.

Si vous compilez avec <=> votre compilateur devrait vous prévenir de ce genre de chose. Faites très attention aux avertissements!

semble fou. Parce que la taille est déclarée comme & Quot; int size & Quot ;, printf (& Quot ... ...% d & Quot;) est définitivement correcte. La taille ne doit pas être différente de & Quot; int & Quot; en taille, parce que vous déclarez explicitement " taille " as int, et cout < < ... taille ... fonctionne correctement.

Avez-vous vérifié que vous avez inclus? Il se peut que sans déclaration appropriée sur votre système, printf fonctionne & "Faux &";.

.

Votre problème est que answer est défini en tant que long long et que vous ne l'imprimez qu'avec un %d.

printf est une fonction varargs. En C, cela signifie que le compilateur ne sait pas les arguments que vous avez passés dans la fonction. Il ne peut pas effectuer ses conversions de type normales et doit faire confiance à son utilisateur pour obtenir les arguments de format corrects, faute de quoi les arguments ne seront pas extraits correctement de la pile d'appels.

Vous n'avez pas bien compris.

Les tailles de vecteurs sont size_t, ce qui, à mon avis, correspond généralement à un long ...

Impossible de dire pourquoi printf ne fonctionne pas.

La méthode size() renvoie size_t, ce qui dépend de votre implémentation c ++. Lorsque vous essayez de printf("%d"), vous indiquez à la bibliothèque de s’attendre à un int, ce qui n’est pas nécessairement le cas; il prend ensuite un printf("%d", (int) size) élément de la pile d'appels, qui ne prend que les octets de poids fort du <=>.

Vous devez forcer la valeur de retour <=> vers un type de données connu avec diffusion: <=>

Quel est le matériel sur lequel vous travaillez? Les chances sont que size est d'un type différent de celui que vous pensez. Imprimez sizeof(size) et cochez ou essayez une %ld. Si vous avez une machine big-endian, comme un PPC, si la taille est long, et si vous imprimez un %d, vous obtenez la fin du long qui contient tous les zéros.

mettre à jour

D'accord, voici ce que je reçois avec 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
$ 

Vous devriez probablement commencer à diviser le code en petits morceaux et à les essayer; il y a quelque chose d'intéressant ici.

Cela fonctionnera:

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

Le problème est que la réponse est longue, longue (un entier de 64 bits) et% d attend un entier de 32 bits. Donc, la taille ne soit pas imprimée. Vous devrez utiliser% lld.

Pour plus d'informations sur les chaînes de format pour printf, consultez: http://fr.wikipedia.org/wiki/Printf

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top