当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);
如果size为int,则应使用<!>“;%d <!>”,而不是<!>;%ld <!>“;。一个好的编译器会警告你这件事。 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
传递给%d
并将其格式化%lld
,但它应该是unsigned long long
,因为它已声明为%ld
。 -
您使用
size
代替int
传递大小。由于-Wall
是和<=>,它应该是<=>。
醇>
当这些args传递给printf时,它会为<=>打印<=>的第一个<=>的前32位和<=>的第二个32位(或更多,超过结束!) 。这不你想要的。
如果使用<=>编译,您的编译器应该警告您这类事情。密切关注警告!
看起来很疯狂。因为size被声明为<!> quot; int size <!> quot ;, printf(<!> quot; ...%d <!> quot;)肯定是正确的。它不能与size_t不同于<!>“int <!>”;大小,因为你明确声明<!> quot; size <!> quot; as int和cout <!> lt; <!> lt; ......大小......工作正常。
你检查过你有没有?可能是因为没有在你的系统上正确声明printf工作<!>“错误<!>”;
您的问题是answer
被定义为long long
而您只能用%d
打印它。
printf是一个varargs函数,在C中表示编译器不知道你传递给函数的参数。它无法进行正常的类型转换,并且必须信任其用户才能正确获取格式参数,否则参数将无法正确地从调用堆栈中拉出。
你做得不对。
矢量大小size_t
,我认为通常是long
...
不能说为什么printf
不起作用。
size()
方法返回size_t
,这取决于您的c ++实现。当您尝试printf("%d")
时,您告诉图书馆期待int
,但情况并非如此;然后从调用堆栈中获取printf("%d", (int) size)
,它只占用<=>的高位字节。
您需要做的是使用强制转换将返回值<=>强制为已知数据类型: <=>
您正在运行的硬件是什么?可能性size
与您的想法不同。打印sizeof(size)
并检查或尝试%ld
。如果你有一个像PPC这样的大端机器,大小是long
,而你打印一个%d
,你就得到了长尾的全零结束。
更新
好的,这就是我使用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
$
您可能应该开始将代码分解成更小的部分并尝试它们;这里有些东西。
这将有效:
std::printf("current last: %**lld** sieve size: %ld\n", answer, size);
问题是答案是长的(64位整数),%d期望32位整数。因此尺寸不会被打印出来。您需要使用%lld。
有关printf签出的格式字符串的更多信息: http://en.wikipedia.org/wiki/Printf