سؤال

من أجل أغراض تصحيح الأخطاء ، هل يمكنني الحصول على رقم الخط في ج/المترجمين C ++؟ (طريقة قياسية أو طرق محددة لبعض المجمعين)

على سبيل المثال

if(!Logical)
    printf("Not logical value at line number %d \n",LineNumber);
    // How to get LineNumber without writing it by my hand?(dynamic compilation)
هل كانت مفيدة؟

المحلول

يجب عليك استخدام الماكرو المسبق __LINE__ و __FILE__. هم وحدات الماكرو المحددة مسبقا وجزء من معيار C/C ++. أثناء المعالجة المسبقة ، يتم استبدالها على التوالي بسلسلة ثابتة تحمل عددًا صحيحًا تمثل رقم السطر الحالي واسم الملف الحالي.

متغيرات أخرى قبل المعالج:

  • __func__ : اسم الوظيفة (هذا جزء من C99, ، لا يدعمها جميع مجمعي C ++)
  • __DATE__ : سلسلة من النموذج "mmm dd yyyy"
  • __TIME__ : سلسلة من النموذج "HH: MM: SS"

سيكون رمزك:

if(!Logical)
  printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);

نصائح أخرى

كجزء من معيار C ++ ، يوجد بعض وحدات الماكرو المحددة مسبقًا التي يمكنك استخدامها. يعرّف القسم 16.8 من معيار C ++ من بين أشياء أخرى ، __LINE__ دقيق.

__LINE__: رقم سطر خط المصدر الحالي (ثابت عشري).
__FILE__: الاسم المفترض للملف المصدر (سلسلة أحرف حرفية).
__DATE__: تاريخ ترجمة الملف المصدر (سلسلة أحرف حرفية ...)
__TIME__: وقت ترجمة الملف المصدر (سلسلة أحرف حرفية ...)
__STDC__: سواء__STDC__ محدد مسبقا
__cplusplus: الاسم __cplusplus يتم تعريفها إلى القيمة 199711L عند تجميع وحدة ترجمة C ++

لذلك سيكون رمزك:

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);

يمكنك استخدام ماكرو بنفس السلوك مثل printf (), ، باستثناء أنه يتضمن أيضًا معلومات التصحيح مثل اسم الوظيفة والفئة ورقم السطر:

#include <cstdio>  //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a,  __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)

يجب أن تتصرف هذه الماكرو بشكل متماثل printf (), ، في حين بما في ذلك معلومات تشبه Java Stacktrace. إليك مثال رئيسي:

void exampleMethod() {
    println("printf() syntax: string = %s, int = %d", "foobar", 42);
}

int main(int argc, char** argv) {
    print("Before exampleMethod()...\n");
    exampleMethod();
    println("Success!");
}

مما يؤدي إلى الإخراج التالي:

Main (main.cpp: 11) قبل examplemethod () ...
examplemethod (main.cpp: 7) printf () بناء جملة: string = foobar ، int = 42
Main (Main.CPP: 13) النجاح!

يستخدم __LINE__ (هذا هو الخط المزدوج لخط inderscore المزدوج) ، سيحل المعالج المسبق محله برقم السطر الذي تمت مواجهته.

الدفع __FILE__ و __LINE__ وحدات الماكرو

محاولة __FILE__ و __LINE__.
قد تجد أيضًا __DATE__ و __TIME__ مفيد.
على الرغم من أنه ما لم يكن عليك تصحيح برنامج عن عملاء ، وبالتالي تحتاج إلى تسجيل هذه المعلومات ، يجب عليك استخدام تصحيح الأخطاء العادية.

نظرًا لأنني أواجه أيضًا هذه المشكلة الآن ولا يمكنني إضافة إجابة إلى سؤال مختلف ولكن ساري المفعول أيضًا هنا، سأقدم حلًا مثالًا لمشكلة: الحصول على رقم سطر فقط من مكان استدعاء الوظيفة في C ++ باستخدام القوالب.

الخلفية: في C ++ يمكن للمرء استخدام قيم عدد صحيح غير النوع كوسيطة قالب. هذا يختلف عن الاستخدام النموذجي لأنواع البيانات كوسائط قالب. وبالتالي فإن الفكرة هي استخدام قيم عدد صحيح هذه لمكالمة وظيفة.

#include <iostream>

class Test{
    public:
        template<unsigned int L>
        int test(){
            std::cout << "the function has been called at line number: " << L << std::endl;
            return 0;
        }
        int test(){ return this->test<0>(); }
};

int main(int argc, char **argv){
    Test t;
    t.test();
    t.test<__LINE__>();
    return 0;
}

انتاج:

تم استدعاء الوظيفة في رقم السطر: 0

تم استدعاء الوظيفة في رقم السطر: 16

شيء واحد نذكره هنا هو أنه في C ++ 11 Standard ، من الممكن إعطاء قيم القالب الافتراضية للوظائف باستخدام القالب. في Pre C ++ 11 ، يبدو أن القيم الافتراضية للوسائط غير النوعية تعمل فقط في وسيطات قالب الفصل. وبالتالي ، في C ++ 11 ، لن تكون هناك حاجة إلى وجود تعريفات وظيفية مكررة على النحو الوارد أعلاه. في C ++ 11 ، من الصحيح أيضًا أن يكون لديك وسيطات قالب Const char* ولكن من غير الممكن استخدامها مع الحرفيين مثل __FILE__ أو __func__ كما ذكر هنا.

لذلك في النهاية إذا كنت تستخدم C ++ أو C ++ 11 ، فقد يكون هذا بديلاً مثيرًا للاهتمام للغاية من استخدام Macro للحصول على خط الاتصال.

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