شرح - read from file c++




القراءة من ملف نصي حتى تكرار EOF السطر الأخير (5)

بدون تعديلات كثيرة في الشفرة الأصلية ، يمكن أن تصبح:

while (!iFile.eof())
{  
    int x;
    iFile >> x;
    if (!iFile.eof()) break;
    cerr << x << endl;
}

لكنني أفضل الحلول الأخرى أعلاه بشكل عام.

هذا السؤال لديه بالفعل إجابة هنا:

يستخدم رمز C ++ التالي كائن ifstream لقراءة أعداد صحيحة من ملف نصي (الذي يحتوي على رقم واحد لكل سطر) حتى يصيب EOF . لماذا تقرأ العدد الصحيح في السطر الأخير مرتين؟ كيف يمكن اصلاح هذا؟

الشفرة:

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ifstream iFile("input.txt");    // input.txt has integers, one per line

    while (!iFile.eof())
    {
        int x;
        iFile >> x;
        cerr << x << endl;
    }

    return 0;
}

input.txt :

10  
20  
30

الإخراج :

10  
20  
30  
30

ملاحظة : لقد تخطيت جميع رموز التحقق من الأخطاء للحفاظ على مقتطف الشفرة صغيرًا. وينظر السلوك أعلاه على Windows (Visual C ++) ، cygwin (gcc) و Linux (gcc).


فقط اتبع عن كثب سلسلة الأحداث.

  • انتزاع 10
  • انتزاع 20
  • انتزاع 30
  • انتزاع EOF

انظر إلى التكرار من الثاني إلى الأخير. أمسكت بـ 30 ، ثم تابعت للتحقق من EOF. لم تصل إلى EOF نظرًا لأن علامة EOF لم تقرأ بعد ("binarically" تحدث ، حيث يكون موقعه المفاهيمي بعد السطر 30 مباشرةً). لذلك قمت بالانتقال إلى التكرار التالي. x لا يزال 30 من التكرار السابق. الآن تقرأ من الدفق وتحصل على EOF. x يبقى 30 و ios :: eofbit مرفوعة. يمكنك الإخراج إلى stderr x (وهو 30 ، تماماً كما في التكرار السابق). بعد ذلك ، تحقق من EOF في حالة الحلقة ، وفي هذه المرة تكون خارج الحلقة.

جرب هذا:

while (true) {
    int x;
    iFile >> x;
    if( iFile.eof() ) break;
    cerr << x << endl;
}

بالمناسبة ، هناك خطأ آخر في التعليمات البرمجية. هل سبق لك أن حاولت تشغيله على ملف فارغ؟ السلوك الذي تحصل عليه هو لنفس السبب بالضبط.


هناك نهج بديل لهذا:

#include <iterator>
#include <algorithm>

// ...

    copy(istream_iterator<int>(iFile), istream_iterator<int>(),
         ostream_iterator<int>(cerr, "\n"));

يحتاج نمط EOF إلى قراءة أولية إلى 'bootstrap' عملية تدقيق EOF. خذ بعين الاعتبار الملف الفارغ لن البداية مجموعة EOF الخاصة به حتى القراءة الأولى. القراءة الأولية سوف التقاط EOF في هذا المثيل و تخطي الحلقة بشكل صحيح.

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

ينبغي أن أشير إلى ما إذا كان الملف فارغًا ، فستتم طباعة الكود المعطى الخاص بك لأن EOF ستحول دون تعيين قيمة إلى x عند الدخول إلى الحلقة.

  • 0

لذا أضف قراءة أولية وحرّك قراءة الحلقة إلى النهاية:

int x;

iFile >> x; // prime read here
while (!iFile.eof()) {
    cerr << x << endl;
    iFile >> x;
}

int x;
ifile >> x

while (!iFile.eof())
{  
    cerr << x << endl;        
    iFile >> x;      
}




fstream