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

你的两个格式字符串都是错误的:

  1. 您将answer传递给%d并将其格式化%lld,但它应该是unsigned long long,因为它已声明为%ld

  2. 您使用size代替int传递大小。由于-Wall是和<=>,它应该是<=>。

  3. 当这些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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top