por que printf mostrar a 0 para o tamanho do vector quando mostra cout o tamanho correto?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu não entendo por que eu recebo 0 quando eu usar printf e% d para obter o tamanho do meu vetor:

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

Se eu iterate através do vetor através

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

Eu recebo o número correto de iterações.

O que estou fazendo errado ou o que está acontecendo com printf? size () retorna um direito int ??


Aqui está o meu script pouco inteira:

#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;
}
Foi útil?

Solução

Agora, com a fonte completo, é claro.

Você declarou:

int size;

Em seguida, você usou:

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

Se o tamanho é int, você deve usar "% d", e não "% ld". Um bom compilador teria avisei sobre isso. GCC dá esses avisos para sua versão original:

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’

Isto diz muito.

Você deve declarar o tamanho como:

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

Em seguida, você deve usá-lo como:

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

Claro, usando iostream evita-lhe estes problemas, especialmente o elenco feio em printf () para transformar o tamanho de um tipo conhecido de printf.

Outras dicas

Esta é estragar porque você tem:

unsigned long long answer = 0;
int size;

e você chamar printf com:

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

Ambos suas cadeias de formato está errado:

  1. Você está passando answer para printf e formatá-lo %d, mas deve ser %lld, uma vez que é declarado unsigned long long.

  2. Você está passando tamanho com %d vez de %ld. Desde size é e int, deve ser %d.

Quando esses argumentos são passadas para printf, está imprimindo os primeiros 32 bits de answer pela primeira %d eo segundo 32 bits (ou mais, após o final!) De answer para o %ld. Esta é não que você quer.

Se você compilar com -Wall seu compilador deve avisá-lo sobre esse tipo de coisa. Preste muita atenção aos avisos!

Parece louco. Porque o tamanho é declarado como "int size", printf ( "...% d") é definitivamente correta. Não pode ser de cerca de size_t sendo diferente de "int" em tamanho, porque você declarar explicitamente "tamanho" como int, e cout << ... tamanho ... funciona corretamente.

Você verificou que você tenha incluído? Pode ser que, sem declaração adequada no seu printf sistema funciona "errado".

Seu problema é que answer é definido como um long long e você só printf-lo com um %d.

printf é um varargs função e em C que significa que o compilador não sabe que argumentos você passado para a função. Ele não pode fazer suas conversões de tipo normal e ele tem que Confiança seu usuário para obter o formato argumentos certos, ou os argumentos não vai ser puxado para fora a pilha de chamadas corretamente.

Você não obtê-lo direito.

tamanhos vetoriais são size_t, que eu acredito que é geralmente um long ...

Não foi possível dizer por printf não está funcionando, apesar de tudo.

O size() método retorna size_t, que depende de sua implementação c ++. Quando você tenta printf("%d"), você está dizendo a biblioteca para esperar um int, que não é necessariamente o caso; Em seguida, leva um int da pilha de chamadas, que está levando apenas o alto-fim bytes do size_t.

O que você precisa fazer é forçar o valor de retorno size() a um tipo de dados conhecido com seleção de elenco: printf("%d", (int) size)

Qual é o hardware que está sendo executado em? As probabilidades são de que size é um tipo diferente do que você pensa. Imprimir sizeof(size) e verificar, ou tentar uma %ld. Se você tem uma máquina big-endian como um PPC, o tamanho é um long, e você imprimir um %d, você obtém os todo-zeros final da longa.

actualizar

Ok, isso é o que eu recebo com um 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
$ 

Você provavelmente deve começar a quebrar o código em pedaços menores e tentando-os; há algo hinky aqui.

Este trabalho:

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

O problema é que a resposta é muito longo (um 64 bit inteiro) e% d espera um número inteiro de 32 bits. Assim, o tamanho não são impressos. Você vai precisar usar% lld.

Para mais informações sobre cadeias de formato para verificação printf out: http://en.wikipedia.org/wiki/Printf

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top