Warum wird printf eine 0 für die Vektorgröße, wenn cout die richtige Größe zeigt?

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

  •  03-07-2019
  •  | 
  •  

Frage

ich nicht, warum ich 0, wenn ich printf und% d verwenden, um die Größe meiner Vektor zu bekommen:

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

Wenn ich durchlaufen den Vektor über

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

Ich bekomme die richtige Anzahl von Iterationen.

Was mache ich falsch oder was mit printf ist oben? Größe () gibt ein int oder ??


Hier ist mein ganzes kleines Skript:

#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;
}
War es hilfreich?

Lösung

Jetzt, mit der kompletten Quelle, ist es klar.

Sie erklärt:

int size;

Dann verwendet man:

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

Wenn Größe int ist, sollten Sie "% d", nicht "% ld" verwenden. Ein guter Compiler würden Sie davor gewarnt. GCC gibt diese Warnungen für Ihre ursprüngliche Version:

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’

Das sagt eine Menge.

Sie sollten erklären Größe wie:

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

Dann sollten Sie es verwenden, wie:

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

Natürlich Iostream mit vermeidet man diese Probleme, speziell das hässliche Casting in printf () Größe einen Typ printf bekannt zu machen.

Andere Tipps

Dies wird vermasseln, weil Sie haben:

unsigned long long answer = 0;
int size;

und rufen Sie printf mit:

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

Ihre beiden Format-Strings sind falsch:

  1. Sie sind vorbei answer printf und Formatierung es %d, aber es sollte %lld werden, da es unsigned long long erklärt wird.

  2. Sie sind vorbei Größe mit %d statt %ld. Da size und int, sollte es %d werden.

Wenn diese Argumente übergeben bekommen printf, es ist das Drucken die ersten 32 Bits von answer zum ersten %d und die zweiten 32 Bit (oder mehr, vorbei am Ende!) Von answer für die %ld. Dies ist nicht , was Sie wollen.

Wenn Sie mit -Wall Compiler kompilieren sollten Sie über diese Art der Sache warnen. Achten Sie sehr genau auf die Warnungen!

Sieht verrückt. Da Größe wird als "int size" erklärt, printf ( "...% d") ist auf jeden Fall richtig. Es kann nicht sein, über size_t anders zu sein als „int“ in Größe, weil Sie explizit „Größe“ als int deklarieren und cout << ... Größe ... richtig funktioniert.

Haben Sie überprüft, dass Sie aufgenommen haben? Es könnte sein, dass ohne entsprechende Erklärung auf Ihrem System printf funktioniert „falsch“.

Ihr Problem ist, dass answer als long long definiert ist und Sie es nur mit einem %d printf.

printf eine varargs Funktion ist und in C, die den Compiler bedeutet nicht weiß, , welche Argumente Sie in die Funktion übergeben. Es kann seine normalen Typkonvertierungen nicht tun, und es hat zu Vertrauen seine Benutzer das Format Argumente richtig zu machen, oder die Argumente nicht den Call-Stack richtig abgezogen werden.

Sie haben es nicht richtig machen.

Vektorgrößen sind size_t, die ich glaube, ist in der Regel ein long ...

kann nicht sagen, warum printf nicht funktioniert, though.

Die size() Methode gibt size_t, die auf Ihrer c ++ Implementierung abhängt. Wenn Sie printf("%d") versuchen, doch sagen Sie die Bibliothek ein int zu erwarten, was nicht unbedingt der Fall ist; es erfolgt dann eine int vom Aufrufliste, die nur die höherwertigen Bytes des size_t findet.

Was Sie tun müssen, um den Rückgabewert size() auf einen bekannten Datentyp mit dem Gießen erzwingen: printf("%d", (int) size)

Was ist die Hardware, die Sie laufen auf? Quoten sind, dass size eine andere Art ist, als Sie denken. Drucken sizeof(size) und überprüfen, oder eine %ld versuchen. Wenn Sie eine Big-Endian-Maschine wie ein PPC haben, die Größe ist ein long, und Sie drucken ein %d, erhalten Sie alle Nullen Ende des langen.

update

Okay, das ist es, was ich mit einem Intel-Mac mini bekommen, 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
$ 

Sie sollten wahrscheinlich starten Sie den Code in kleinere Stücke brechen und versuchen, sie; es gibt etwas hinky hier.

Dies funktioniert:

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

Das Problem ist, dass Antwort ist eine lange lange (eine 64-Bit-Ganzzahl) und% d erwartet eine 32-Bit-Ganzzahl. So bekommen Größe nicht gedruckt. Sie müssen% LLD verwenden.

Weitere Informationen über die Formatstrings für printf Check-out: http://en.wikipedia.org/wiki/Printf

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top