سؤال

أقوم في البداية ببناء آلية تشبه الفهرس ، وقراءة كل سطر من textfile باستخدام GetLine ، والتحقق مما إذا كان يطابق إعلان رأس معروف (String.compare) وحفظ موضع tellg كفهرس لهذا النقطة. نيتي هي استخدام Seekg (الفهرس ، iOS :: التسول) للبحث عن المكان في الملف الذي يوجد فيه الرأس. بعد قراءة الملف مرة واحدة عند إنشاء الفهرس الخاص بي والاتصال SEERG (0 ، iOS :: BEGR) ، يقوم GetLine التالي بإرجاع سلسلة فارغة حيث أتوقع رؤية السطر الأول في الملف.

جزء من الكود الخاص بي أدناه لتسليط الضوء بشكل أفضل على مشكلتي

//build the index
while (! m_fileIn.eof())
{
   getline (m_fileIn,lineRead);
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

// start reading the file data
m_fileIn.seekg(0,ios::beg);
//read first line (title)

تُرجع وظيفة getLineID INT اعتمادًا على نتيجة مقارنة السلسلة.

هل استخدام GetLine غير صحيح إذا كنت بحاجة إلى إعادة قراءة الملف؟

هل كانت مفيدة؟

المحلول

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

// After the loop reset the Bad Bits.
m_fileIn.clear()

ملاحظة: الشيء السيئ هو أحد شروط الأخطاء العديدة بما في ذلك EOF

لكن هذه ليست مشاكلك الرئيسية:

أنت تستخدم Classic anti pattern لقراءة ملف:
بدلا من ذلك استخدم هذا.

while (getline (m_fileIn,lineRead))
{
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

المشكلة هي أنه لم يتم تعيين EOF حتى تقرأه.
القراءة الأخيرة صالحة تقرأ حتى ولكن لا تتجاوز EOF (وبالتالي لم يتم تعيين EOF).

لذا فكر في الموقف الذي قرأت فيه السطر الأخير في الملف. لم يتم تعيين EOF لأنك لم تقرأ الماضي. لذلك يتم إدخال الحلقة. يمكنك الآن تنفيذ GetLine (). هذا يحاول قراءة EOF الماضي لأنه لا توجد بيانات على الإطلاق للقراءة (وليس بايت واحد). لذا فإن GetLine () تفشل الآن ، فأنت تتصل بـ getLineId () باستخدام LinerEad التي تكون قيمتها غير محددة (المعيار لا يقول ما يحدث لـ Lineread عندما يتم ضرب حالة EOF ؛ لكن من المحتمل أن يكون لها قيمة الخط الأخير كما يبدو أنك لا تبدو لإعادة ضبطها داخل الحلقة).

مشكلة أخرى في هذا الرمز هي أنه يتحقق فقط من EOF. ماذا يحدث عندما يحدث نوع آخر من الخطأ؟ حلقة في الواقع تتعثر في حلقة لا حصر لها. هذا لأنه عندما يتم تعيين علامة خطأ لا يحدث أي قراءة حتى لا تتمكن من الوصول إلى EOF.

while (! m_fileIn.eof())
{
   getline (m_fileIn,lineRead)
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

الحل هو إجراء عملية القراءة في اختبار حلقة. هذا يعمل لأن getline () إرجاع التيار تم تمريره كمعلمة الأولى. لذلك يتم استخدام الدفق في سياق منطقي. عند استخدام دفق في سياق منطقي ، يتم تحويله إلى نوع يمكن استخدامه كنوع منطقي ؛ قيمة هذا الكائن تعادل صحيحة إذا لم تكن هناك أخطاء وخطأ خلاف ذلك.

في هذه الحالة ، تتم محاولة القراءة ، ولكن إذا فشلت ، لم يتم إدخال الحلقة أبدًا.

نصائح أخرى

بعد النشر هنا وصوب مواقع الويب المختلفة ، أضفت الخط

m_fileIn.clear();

قبل الخط

getline (m_fileIn,lineRead);

عن طريق مسح أعلام الخطأ (أفترض خطأ EOF) تمكنت من الاستمرار في ذلك المعتاد.

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

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