当cout显示正确的大小时,为什么printf为矢量大小显示0?

时间:2009-03-02 03:20:31

标签: c++ vector printf

当我使用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;
}

8 个答案:

答案 0 :(得分:6)

现在,有了完整的消息来源,很明显。

你宣布:

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已知的类型。

答案 1 :(得分:5)

这搞砸了,因为你有:

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。< / p>

  2. 您使用%d代替%ld传递尺寸。由于sizeint,因此应为%d

  3. 当这些args传递给printf时,它会为answer的第一个%d和第二个32位(或更多,超过结束!)打印answer的前32位} %ld。这你想要的。

    如果使用-Wall进行编译,编译器应该警告您这类事情。密切关注警告!

答案 2 :(得分:2)

看起来很疯狂。因为size被声明为“int size”,所以printf(“...%d”)肯定是正确的。它的大小不能与size_t不同,因为你明确地将“size”声明为int,而cout&lt;&lt; ......大小......工作正常。

你检查过你有没有?可能是因为没有在你的系统上正确声明printf工作“错误”。

答案 3 :(得分:2)

您的问题是,answer被定义为long long,您只能使用%d进行打印。

printf是一个varargs函数,在C中表示编译器不知道你传递给函数的参数。它无法进行正常的类型转换,并且必须信任其用户才能正确获取格式参数,否则参数将无法正确地从调用堆栈中拉出。

你做得不对。

答案 4 :(得分:1)

矢量大小为size_t,我认为通常是long ...

但不能说为什么printf无效。

答案 5 :(得分:1)

您正在运行的硬件是什么?可能性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
$ 

您可能应该开始将代码分解成更小的部分并尝试它们;这里有些东西。

答案 6 :(得分:1)

size()方法返回size_t,这取决于您的c ++实现。当您尝试printf("%d")时,您告诉图书馆期待int,但情况并非如此;然后它从调用堆栈中获取int,它只占用size_t的高位字节。

您需要做的是使用强制转换将返回值size()强制为已知数据类型: printf("%d", (int) size)

答案 7 :(得分:0)

这将有效:

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

问题是答案是长的(64位整数),%d期望32位整数。因此尺寸不会被打印出来。您需要使用%lld。

有关printf签出的格式字符串的更多信息: http://en.wikipedia.org/wiki/Printf