رقم سطر C/C ++
-
27-09-2019 - |
سؤال
من أجل أغراض تصحيح الأخطاء ، هل يمكنني الحصول على رقم الخط في ج/المترجمين 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 للحصول على خط الاتصال.