Fgets في C++ يكرر السطر الأخير
سؤال
لدي برنامج مثل (من نص الرابط)
FILE* soubor;
char buffer[100];
soubor = fopen("file","r");
string outp = "";
while (! feof(soubor))
{
fgets(buffer,100,soubor);
fputs (buffer , stdout);
}
fclose(soubor);
وملف مثل
A
B
C
D
E
وإخراج البرنامج هو
A
B
C
D
E
E
يكرر السطر الأخير من الملف مرتين.لدي هذه المشكلة في البرامج الأخرى أيضا.
المحلول
feof()
كشرط لحلقة لقراءة من ملف يؤدي دائما تقريبا للمشاكل. والطريقة القياسية تبدو هذه:
while (fgets(buffer, 100, infile))
fputs(buffer, stdout);
نصائح أخرى
والمشكلة هي أن السطر الأخير، ستفشل fgets. ومع ذلك فإنك عدم التحقق feof حتى الحلقة القادمة، لذلك كنت لا تزال الدعوة fputs التي سوف طباعة محتويات المخزن، أي السطر السابق.
وجرب هذا:
FILE* soubor;
char buffer[100];
soubor = fopen("file","r");
string outp = "";
while (true)
{
fgets(buffer,100,soubor);
if (feof(soubor))
break;
fputs (buffer , stdout);
}
fclose(soubor);
وأنا أحب بن Russels الجواب. هذا هو الإصدار بلدي لتجنب تكرار السطر الأخير في التعليمات البرمجية ج. يعمل ولكن أنا لا أفهم لماذا، لأن الشرط if (fgets != NULL)
ينبغي القيام بهذا العمل.
int main ()
{
FILE* pFile;
char name[41] = "fileText04.txt";
char text[81];
int i;
pFile = fopen("fileText04.txt", "wt");
if (pFile == NULL)
{
printf("Error creating file \n");
exit(1);
}
else
{
for (i=0; i<5; i++)
{
printf("Write a text: \n");
fgets(text, 81, stdin);
fputs(text, pFile);
}
}
fclose (pFile);
pFile = fopen(name, "rt");
if (pFile == NULL)
{
printf("File not found. \n");
exit(2);
}
while (! feof(pFile))
{
fgets(text, 80, pFile);
if (feof(pFile)) // This condition is needed to avoid repeating last line.
break; // This condition is needed to avoid repeating last line.
if (fgets != NULL)
fputs(text, stdout);
}
fclose (pFile);
return 0;
}
وشكرا جزيلا، خايمي Daviu
السبب في أن feof(inputfile_pointer) ليست الطريقة الصحيحة للتحقق من الإنهاء عند نسخ الملف، لأنه لا يعمل في كلاهما من الحالات التالية:
- ينتهي الملف بدون حرف السطر الجديد.
- ينتهي الملف بحرف السطر الجديد.
دليل:
- افترض
feof
يتم فحصه بعدfgets()
, ، لكن قبلfputs()
.ثم لا يعمل للحالة 1.أعلاه، مهما كانت الشخصياتfgets()
يقرأ قبل EOF، لن يتم استخدامه من قبلfputs()
. - يفترض
feof
يتم فحصه بعدfputs()
, ، لكن قبلfgets()
.ثم لا يعمل للحالة 2.أعلاه، كما هو الحال عندماfgets()
أخيرًا واجه EOF، ولا يقوم بالكتابة فوق سلسلة المخزن المؤقت بأي شيء جديد، وكماfputs()
يُسمح بتشغيله مرة أخرى، وسيضع في ملف الإخراج نفس محتوى سلسلة المخزن المؤقت كما في التكرار السابق؛ومن ثم تكرار السطر الأخير في ملف الإخراج.