Cout이 올바른 크기를 표시 할 때 Printf가 벡터 크기에 대해 0을 표시하는 이유는 무엇입니까?

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

  •  03-07-2019
  •  | 
  •  

문제

벡터의 크기를 얻기 위해 printf와 %d를 사용할 때 0을 얻는 이유를 알지 못합니다.

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

내가 벡터를 통해 반복한다면

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

올바른 반복을 얻습니다.

내가 무엇을 잘못하고 있는가, 또는 printf는 무엇입니까? size () int 오른쪽을 반환합니까?


내 작은 스크립트는 다음과 같습니다.

#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;
}
도움이 되었습니까?

해결책

이제 완전한 소스로 분명합니다.

당신은 선언했다 :

int size;

그런 다음 사용했습니다.

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

크기가 int 인 경우 "%ld"가 아닌 "%d"를 사용해야합니다. 좋은 컴파일러가 이것에 대해 경고했을 것입니다. GCC는 원래 버전에 대한 이러한 경고를 제공합니다.

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’

이것은 많은 것을 말합니다.

크기를 다음과 같이 선언해야합니다.

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

그런 다음 다음과 같이 사용해야합니다.

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

물론, ioStream을 사용하면 이러한 문제, 특히 printf ()의 못생긴 캐스팅을 피하기 위해 크기를 printf로 알려진 유형으로 변환합니다.

다른 팁

당신이 가지고 있기 때문에 이것은 망쳐 놓았습니다.

unsigned long long answer = 0;
int size;

그리고 당신은 전화합니다 printf 와 함께:

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

두 형식 문자열 모두 잘못되었습니다.

  1. 당신은 지나가고 있습니다 answer 에게 printf 그리고 그것을 포맷합니다 %d, 그러나 그럴 것입니다 %lld, 선언 된 이후 unsigned long long.

  2. 당신은 크기를 통과합니다 %d 대신에 %ld. 부터 size 이고 int, 그것은해야한다 %d.

그 args가 printf로 전달되면 처음 32 비트를 인쇄합니다. answer 처음으로 %d 그리고 두 번째 32 비트 (또는 끝을 지나서!) answer%ld. 이것은 ~ 아니다 당신이 원하는 것.

당신이 컴파일하는 경우 -Wall 컴파일러는 이런 종류의 것에 대해 경고해야합니다. 경고에 매우주의를 기울이십시오!

미쳤어 보인다. 크기는 "int size"로 선언되므로 printf ( "...%d")는 확실히 정확합니다. "size"를 int로 명시 적으로 선언하고 cout << ... 크기가 올바르게 작동하기 때문에 크기가 크기가 크게 다를 수 없습니다.

포함 된지 확인 했습니까? 시스템에 적절한 선언이 없으면 Printf가 "잘못"작동 할 수 있습니다.

당신의 문제는 그 것입니다 answer a로 정의됩니다 long long 그리고 당신은 단지 그것을 a로 인쇄합니다 %d.

printf는 varargs 함수이며 C에서 컴파일러를 의미합니다. 모릅니다 당신이 기능으로 전달한 주장. 정상적인 유형 변환을 수행 할 수 없으며 신뢰하다 사용자가 형식 인수를 올바르게 얻거나 인수가 통화 스택에서 올바르게 꺼지지 않습니다.

당신은 그것을 제대로 얻지 못했습니다.

벡터 크기입니다 size_t, 내가 믿는 것은 보통 a long...

이유를 말할 수 없었습니다 printf 그래도 작동하지 않습니다.

그만큼 size() 메소드 리턴 size_t, C ++ 구현에 따라 다릅니다. 당신이 시도 할 때 printf("%d"), 당신은 도서관에 기대하고 있습니다 int, 반드시 그런 것은 아닙니다. 그런 다음 사용됩니다 int 호출 스택에서 size_t.

당신이해야 할 일은 반환 값을 강요하는 것입니다 size() 캐스팅이있는 알려진 데이터 유형으로 :printf("%d", (int) size)

What's the hardware you're running on? Odds are that size is a different type than you think. Print sizeof(size) and check, or try a %ld. If you have a big-endian machine like a PPC, size is a long, and you print a %d, you get the all-zeros end of the long.

update

Okay, this is what I get with an 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
$ 

You probably should start breaking the code up into smaller pieces and trying them; there's something hinky here.

This will work:

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

The problem is that answer is a long long (a 64 bit integer) and %d expects a 32bit integer. So size doesn't get printed. You will need to use %lld.

For more information on format strings for printf check out: http://en.wikipedia.org/wiki/Printf

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top