Cout이 올바른 크기를 표시 할 때 Printf가 벡터 크기에 대해 0을 표시하는 이유는 무엇입니까?
문제
벡터의 크기를 얻기 위해 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);
두 형식 문자열 모두 잘못되었습니다.
당신은 지나가고 있습니다
answer
에게printf
그리고 그것을 포맷합니다%d
, 그러나 그럴 것입니다%lld
, 선언 된 이후unsigned long long
.당신은 크기를 통과합니다
%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