Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么fwrite写的比我告诉它的要多?_C_File_Fwrite_Ftell - Fatal编程技术网

C 为什么fwrite写的比我告诉它的要多?

C 为什么fwrite写的比我告诉它的要多?,c,file,fwrite,ftell,C,File,Fwrite,Ftell,输出: 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)); 发生了什么事? write设置为25755,我告

输出:

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));
发生了什么事?
write设置为25755,我告诉fwrite将这么多字节写入一个文件,它位于文件的开头,然后我将位于25755之外的位置?

如果您使用的是Dossish系统(比如Windows),并且文件未以二进制模式打开,那么行尾将自动转换,并且每行将添加一个字节

因此,指定
“wb”
作为模式,而不仅仅是@caf指出的
“w”
。它对类Unix平台没有影响,在其他平台上也会做正确的事情

例如:

0
25755
25868
#包括
#定义LF 0x0a
内部主(空){
字符x[]={LF,LF};
文件*out=fopen(“测试”,“w”);
printf(“%d”,ftell(out));
fwrite(x,1,sizeof(x),out);
printf(“%d”,ftell(out));
fclose(out);
返回0;
}
使用VC++: C:\Temp>cl y.C 针对80x86的Microsoft(R)32位C/C++优化编译器版本15.00.21022.08 版权所有(C)微软公司。版权所有。 y、 c Microsoft(R)增量链接器版本9.00.21022.08 版权所有(C)微软公司。版权所有。 /输出:y.exe C:\Temp>y.exe 04 使用Cygwin gcc: /cygdrive/c/Temp$gcc y.c-o y.exe /cygdrive/c/Temp$/y.exe 02
这可能取决于打开文件的模式。如果将其作为文本文件打开,则在DOS/Windows系统中,
\n
可能被写成
\r\n
。但是,
ftello64()
可能只给出二进制文件指针,该指针将计入额外写入的
\r
字符中。尝试清除任何
\n
数据的
exputf[]
,或尝试以二进制文件打开输出文件(
“wb”
,而不是
“w”
)。

有趣。在Windows VC++上运行良好,但将
ftello64
替换为
ftell

变量
write
未初始化,因此数组的大小和写入量基本上是随机的。

…您可以使用
“wb”
而不是
fopen()中的
“w”
以二进制模式打开
。基于OP在[mingw]和[cygwin]标记中的(轻微)存在,我怀疑这就是答案。这很奇怪,因为cygwin安装程序询问要使用哪种类型的行尾(并推荐Unix样式)。@Sinan-是的,但mingw可能会使用本机行尾,因此,在两种环境之间切换时会引起轻微的混乱。“对他人做正确的事情”不是正确的思考方式。DOS/CPM和UNIX只是在其体系结构中做出了不同的决策。DOS决定将回车符和换行符的概念分开,而UNIX决定只在换行符中合并这些概念。在UNIX中,“wb”和“w”之间没有真正的区别,这意味着在“错误模式”下打开和关闭文件时,您不会犯“神秘的错误”。OTOH,DOS分离了换行和回车的概念,这与行打印机语义相匹配。作为旁注,您可能应该使用
size\u t
进行
write
而不是
unsigned int
,而
新的
操作符在C语言中做什么?我怀疑它是用真实代码初始化的,OP只是过度保护在公共网站上发布生产代码。是的,在重读这个问题之后,我同意这不可能是原始问题的原因——我认为思南的答案可能是正确的。但万一它是原始代码的直接副本,我会把我的答案留在这里。
#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;
}
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 /cygdrive/c/Temp $ gcc y.c -o y.exe /cygdrive/c/Temp $ ./y.exe 02