سؤال

لقد كنت أتساءل، ما هو الهدف من الانسداد؟بقدر ما أستطيع أن أقول، انسداد هو نفس cerr ولكن مع التخزين المؤقت لذلك فهو أكثر كفاءة.عادةً ما يكون stderr هو نفس stdout، لذا فإن clog هو نفس cout.يبدو هذا سخيفًا جدًا بالنسبة لي، لذا أعتقد أنني يجب أن أسيء فهمه.إذا كانت لدي رسائل سجل تخرج إلى نفس المكان الذي توجد به رسائل خطأ تخرج إليه (ربما شيء ما في /var/log/messages)، فمن المحتمل أنني لا أكتب كثيرًا (لذلك لا يضيع الكثير باستخدام غير - مخزنة مؤقتا).في تجربتي، أريد تحديث رسائل السجل الخاصة بي (غير مخزنة مؤقتًا) حتى أتمكن من المساعدة في العثور على العطل (لذلك لا أريد استخدام الانسداد المخزن مؤقتًا).من الواضح أنني يجب أن أستخدم cerr دائمًا.

أود أن أكون قادرًا على إعادة توجيه الانسداد داخل برنامجي.سيكون من المفيد إعادة توجيه cerr بحيث عندما أقوم باستدعاء روتين المكتبة، يمكنني التحكم في المكان الذي يذهب إليه cerr وclog.هل يمكن لبعض المترجمين دعم هذا؟لقد قمت للتو بالتحقق من DJGPP وتم تعريف stdout على أنه عنوان بنية FILE، لذلك من غير القانوني القيام بشيء مثل "stdout = freopen(...)".

  • هل من الممكن إعادة توجيه clog و cerr و cout و stdin و stdout و/أو stderr؟
  • هل الفرق الوحيد بين السدادة و cerr هو التخزين المؤقت؟
  • كيف يمكنني تنفيذ (أو العثور على) وسيلة تسجيل أكثر قوة (الروابط من فضلك)؟
هل كانت مفيدة؟

المحلول

هل من الممكن إعادة توجيه clog و cerr و cout و stdin و stdout و/أو stderr؟

نعم.تريد rdbuf وظيفة.

ofstream ofs("logfile");
cout.rdbuf(ofs.rdbuf());
cout << "Goes to file." << endl;

هل الفرق الوحيد بين السدادة و cerr هو التخزين المؤقت؟

بقدر ما أعرف، نعم.

نصائح أخرى

إذا كنت في بيئة Posix Shell (أفكر حقًا في Bash) ، فيمكنك إعادة توجيه أي واصف ملف إلى أي واصف ملف آخر ، حتى يتم إعادة التوجيه ، يمكنك فقط:

$ myprogram 2>&5 

لإعادة توجيه stderr إلى الملف الذي يمثله fd=5.

يحرر:بعد التفكير مرة أخرى، تعجبني إجابة @Konrad Rudolph حول إعادة التوجيه بشكل أفضل.تُعد rdbuf() طريقة أكثر تماسكًا وقابلية للحمل للقيام بذلك.

أما بالنسبة للتسجيل، حسنًا... سأبدأ بمكتبة Boost لكل الأشياء التي تتعلق بـ C++ غير الموجودة في المكتبة القياسية.هوذا: تعزيز التسجيل v2

يحرر:تعزيز التسجيل هو لا جزء من مكتبات Boost؛تمت مراجعته، ولكن لم يتم قبوله.

يحرر:بعد عامين، في مايو 2010، وافق Boost على مكتبة التسجيل، التي تسمى الآن Boost.Log.

وبطبيعة الحال، هناك بدائل:

  • Log4Cpp (واجهة برمجة تطبيقات بأسلوب log4j لـ C++)
  • Log4Cxx (واجهة برمجة تطبيقات نمط log4j التي ترعاها Apache)
  • بانثيوس (البائد؟آخر مرة حاولت فيها لم أتمكن من البناء على مترجم حديث)
  • جوجل لوج (نصيحة القبعة @SuperElectric)

يوجد أيضًا مسجل أحداث Windows.

واثنين من المقالات التي قد تكون ذات فائدة:

المسجل الأساسي

#define myerr(e) {CriticalSectionLocker crit; std::cerr << e << std::endl;}

تستعمل ك myerr("ERR: " << message); أو myerr("WARN: " << message << code << etc);

فعالة جدا.

ثم افعل:

./programname.exe 2> ./stderr.log
perl parsestderr.pl stderr.log

أو فقط قم بتحليل stderr.log يدويًا

أعترف أن هذا ليس ل لأقصى حد كود الأداء الحرج.ولكن من يكتب ذلك على أي حال.

نظرًا لوجود العديد من الإجابات هنا حول إعادة التوجيه، سأضيفها هذه الجوهرة الجميلة لقد تعثرت مؤخرًا بشأن إعادة التوجيه:

#include <fstream>
#include <iostream>

class redirecter
{
public:
    redirecter(std::ostream & dst, std::ostream & src)
        : src(src), sbuf(src.rdbuf(dst.rdbuf())) {}
    ~redirecter() { src.rdbuf(sbuf); }
private:
    std::ostream & src;
    std::streambuf * const sbuf;
};

void hello_world()
{
    std::cout << "Hello, world!\n";
}

int main()
{
    std::ofstream log("hello-world.log");
    redirecter redirect(log, std::cout);
    hello_world();
    return 0;
}

إنها في الأساس فئة إعادة توجيه تسمح لك بإعادة توجيه أي دفقين واستعادتهما عند الانتهاء.

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