下面的代码应该将文件的内容转换为大写(如果需要转换,它将用大写替换原始字符)。该代码适用于Mac OS和Linux。但是在Windows上,转换在第二个字母处停止,并且写入第二个字母(大写)永远不会在文件中结束。
实施例
来源数据:
ASDF
的结果:
ASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS ...
我不明白,为什么它在其他平台上工作,但对于Windows。
我非常感谢任何解释。
问候,eljobso
#include <stdio.h>
#include <stdlib.h>
int to_upper_file(FILE *fp)
{
char ch = ' ';
if (fp == NULL)
{
perror("Unable to open file");
exit(0);
}
else
{
while (ch != EOF)
{
ch = fgetc(fp);
if ((ch >= 'a') && (ch <= 'z'))
{
ch = ch - 32;
fseek(fp, -1, SEEK_CUR);
fputc(ch, fp);
}
}
}
fclose(fp);
return 0;
}
int main(void)
{
FILE *fp;
int status;
char filename[20];
printf("Enter filename:");
scanf("%s", filename);
fp = fopen(filename, "r+");
if(!fp)
{
printf("File error.\n");
exit(0);
}
else
{
status = to_upper_file(fp);
if (status == 0)
{
printf("Conversion success.\n");
}
if (status == -1)
{
printf("Conversion failure.\n");
}
}
return 0;
}
答案 0 :(得分:4)
由于FILE *
上的操作的缓冲性质,在读取和写入之间切换或写入和读取以执行文件定位操作或(对于后者)只需要刷新时是必要的。
来自MSDN documentation to fopen()
:
当&#34; r +&#34;,&#34; w +&#34;,或&#34; a +&#34;指定了访问类型,允许读取和写入(该文件被称为打开&#34;更新&#34;)。但是,当您从读取切换到写入时,输入操作必须遇到EOF标记。如果没有EOF,则必须使用对文件定位功能的干预调用。文件定位功能是fsetpos,fseek和rewind。当您从写入切换到读取时,必须使用fflush或文件定位功能进行干预。
要让您的代码满足此规则,您可能希望添加0
- 在放置字符后进行搜索,如下所示:
fseek(fp, -1, SEEK_CUR);
fputc(ch, fp);
fseek(fp, 0, SEEK_CUR);
另外你也可以刷新文件:
fseek(fp, -1, SEEK_CUR);
fputc(ch, fp);
fflush(fp);
还应该提到的是,应该对所有相关的系统调用进行错误检查。
<强>更新强>
来自C11标准(7.21.5.3/7 fopen
功能)(我的斜体):
使用更新模式打开文件时(&#39; +&#39;作为第二个或第三个字符) 在上面的模式参数值列表中,输入和输出都可以在上面执行 相关流。但是,输出不应该直接跟在输入之后没有 干预调用fflush函数或文件定位函数(fseek, fsetpos,或倒带),输入不应该直接跟随输出没有 干预调用文件定位功能,除非输入操作遇到以下情况 文件。 [...]