لماذا printf تظهر 0 حجم ناقلات عندما cout يظهر الصحيحة الحجم ؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

أنا لا أفهم لماذا أحصل 0 عند استخدام printf و %d للحصول على حجم ناقلات:

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?حجم() بإرجاع عدد صحيح أليس كذلك ؟ ؟


هنا هو بلدي كامل السيناريو قليلا:

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

وإذا كان حجم هو كثافة العمليات، يجب عليك استخدام "٪ د"، وليس "٪ دينار". ومن شأن مترجم جيد وحذر لكم عن هذا. يعطي دول مجلس التعاون الخليجي هذه التحذيرات لعرض الأصلي:

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 إلى printf و تنسيق %d, ولكن ينبغي أن يكون %lld, بما أنه أعلن unsigned long long.

  2. كنت تمر الحجم مع %d بدلا من %ld.منذ size و int, ، ينبغي أن يكون %d.

عند تلك وسائط الحصول على تمرير إلى printf انه الطباعة الأول 32 بت answer الأولى %d والثاني 32 بت (أو أكثر, الماضي النهاية!) من answer عن %ld.هذا هو لا ما تريد.

إذا كنت تجميع مع -Wall المترجم الخاص بك يجب أن يحذرك حول هذا النوع من الشيء.إيلاء اهتمام وثيق جدا إلى التحذيرات!

ويبدو مجنون. لأن يعلن حجم و"حجم كثافة"، printf ( "...٪ د") هو الصحيح بالتأكيد. لا يمكن أن يكون حول size_t كونها تختلف عن "كثافة" في الحجم، لأنك يعلن صراحة "حجم" ك int، ومحكمة << ... حجم ... يعمل بشكل صحيح.

هل راجعت أن قمت بتضمين؟ قد يكون ذلك دون إعلان السليم على printf النظام الخاص بك يعمل "خاطئة".

المشكلة هي أن answer ويعرف long long وأنت فقط printf مع %d.

printf هو varargs وظيفة في C يعني مترجم لا يعرف ما الحجج التي تم تمريرها إلى الدالة.فإنه لا يمكن القيام النوع العادي التحويلات و يجب أن الثقة المستخدم للحصول على شكل حجج الحق ، أو الحجج لن يتم سحب الاستدعاءات بشكل صحيح.

لم تحصل على هذا الحق.

وأحجام ناقلات هي size_t، التي أعتقد أنها عادة ما تكون long ...

لا أستطيع أن أقول لماذا printf لا يعمل، على الرغم من.

وطريقة size() يعود size_t، الذي يعتمد على ج ++ التطبيق الخاص بك. عند محاولة printf("%d")، أنت تقول المكتبة أن نتوقع int، وهي ليست بالضرورة في القضية؛ بعد ذلك يأخذ int من مكدس الاستدعاءات التي تتخذ فقط بايت ذات الترتيب العالي من size_t.

ما عليك القيام به هو إجبار size() قيمة الإرجاع إلى نوع البيانات المعروفة مع الصب: printf("%d", (int) size)

ما هي الأجهزة التي تقوم بتشغيل في؟ الاحتمالات هي أن size هو نوع مختلف مما كنت اعتقد. طباعة sizeof(size) والاختيار، أو محاولة %ld. إذا كان لديك جهاز الكبيرة endian مثل PPC، حجم هو long، وقمت بطباعة %d، تحصل نهاية كل الأصفار من فترة طويلة.

تحديث

حسنا، وهذا هو ما يحصل مع إنتل ماك ميني، 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
$ 

وربما كنت ينبغي أن تبدأ كسر رمز تصل إلى أجزاء أصغر ومحاكمتهم. هناك شيء hinky هنا.

وهذا سيعمل:

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

والمشكلة هي أن الجواب هو طويل (عدد صحيح 64 بت) و٪ d يتوقع عدد صحيح 32BIT و. لذلك الحجم لا تحصل على المطبوعة. سوف تحتاج إلى استخدام٪ بكالوريوس في القانون.

لمزيد من المعلومات حول سلاسل التنسيق لفحص printf من: http://en.wikipedia.org/wiki/Printf

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top