لماذا يكتب اللوكيون أكثر مما أخبره؟
سؤال
FILE *out=fopen64("text.txt","w+");
unsigned int write;
char *outbuf=new char[write];
//fill outbuf
printf("%i\n",ftello64(out));
fwrite(outbuf,sizeof(char),write,out);
printf("%i\n",write);
printf("%i\n",ftello64(out));
انتاج:
0
25755
25868
ما الذي يجري؟ تم تعيين الكتابة على 25755 ، وأخبر Fwrite أن يكتب أن العديد من البايتات إلى ملف ، وهو في البداية ، ثم أنا في وضع بجانب 25755؟
المحلول
إذا كنت على نظام مجدهر (على سبيل المثال ، Windows) ولم يتم فتح الملف في الوضع الثنائي ، فسيتم تحويل نهاية الخطوط تلقائيًا وسيضيف كل "سطر" بايت واحد.
لذلك ، حدد "wb"
كوضع وليس فقط "w"
كما يشير CAF. لن يكون له أي تأثير على منصات UNIX وسوف تفعل الشيء الصحيح على الآخرين.
فمثلا:
#include <stdio.h>
#define LF 0x0a
int main(void) {
char x[] = { LF, LF };
FILE *out = fopen("test", "w");
printf("%d", ftell(out));
fwrite(x, 1, sizeof(x), out);
printf("%d", ftell(out));
fclose(out);
return 0;
}
مع VC ++:
C:\Temp> cl y.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. y.c Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:y.exe C:\Temp> y.exe 04
مع Cygwin GCC:
/cygdrive/c/Temp $ gcc y.c -o y.exe /cygdrive/c/Temp $ ./y.exe 02
نصائح أخرى
قد يعتمد على الوضع الذي فتحت فيه الملف. إذا فتحته كملف نصي ، فعندئذٍ \n
قد تكتب على أنها \r\n
في أنظمة DOS/Windows. لكن، ftello64()
ربما يعطي فقط مؤشر الملف الثنائي ، والذي سيحسب في الإضافية \r
شخصيات مكتوبة. حاول مسح outbuf[]
من أي \n
البيانات أو محاولة فتح الملف Out باعتباره ثنائيًا ("wb"
بدلاً من "w"
).
المتغير write
غير مهذب ، وبالتالي فإن حجم الصفيف والمبلغ المكتوب سيكون عشوائيًا بشكل أساسي.
مثير للإعجاب. يعمل بشكل جيد على Windows VC ++ ، وإن كان ذلك ftello64
تم استبداله ب ftell
.