我编写了一个简单的C程序,它接受.txt
文件并用连字符替换所有空格。但是,程序进入无限循环,结果是连续的连字符数组。
这是输入文件:
a b c d e f
这是进程崩溃后的文件:
a----------------------------------------------------------------------------
----------------------------------------... (continues thousands of times)...
我想是fread()
,fwrite()
和fseek()
意外行为的原因,或者我对这些功能的误解。这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#define MAXBUF 1024
int main(void) {
char buf[MAXBUF];
FILE *fp;
char c;
char hyph = '-';
printf("Enter file name:\n");
fgets(buf, MAXBUF, stdin);
sscanf(buf, "%s\n", buf); /* trick to replace '\n' with '\0' */
if ((fp = fopen(buf, "r+")) == NULL) {
perror("Error");
return EXIT_FAILURE;
}
fread(&c, 1, 1, fp);
while (c != EOF) {
if (c == ' ') {
fseek(fp, -1, SEEK_CUR); /* rewind file position indicator to the position of the ' ' */
fwrite(&hyph, 1, 1, fp); /* write '-' instead */
}
fread(&c, 1, 1, fp); /* read next character */
}
fclose(fp);
return EXIT_SUCCESS;
}
这里有什么问题?
答案 0 :(得分:2)
你有两个问题:
1)您应该检查fread是否返回您请求的项目数,例如你得到1回。
2)然后你应该检查feof(fp),而不是将你读到的字符与EOF进行比较。这将告诉您,由于EOF或其他原因,您的阅读是否返回了较少/没有项目。
答案 1 :(得分:2)
你有一些问题......
检查标准C库函数返回的类型以及返回值的含义。
std C库将EOF
定义为整数 -1。由于完整字符集为256个字符且char类型可以容纳0到255(256个diff值),因此必须使EOF
成为整数。
除了所有的咆哮之外......你还在错误地检查EOF
。
问题,拼写出来:
您应该检查fread
if( fread(&c, 1, 1, fp) != 1 )
{
// Handle the error
}
// `EOF` is the integer -1. It will not fit in a char. So, your while loop becomes endless unless you get a -1 in the data stream
// The "correct" way to do what you want to do is using the stdlib function feof(fp)
while( !feof( fp ) )
{
if (c == ' ')
{
// You should check the value returned by fseek for errors
fseek(fp, -1, SEEK_CUR); /* rewind file position indicator to the position of the ' ' */
// You should check the value returned by fwrite for errors
fwrite(&hyph, 1, 1, fp); /* write '-' instead */
}
if( fread(&c, 1, 1, fp) != 1 )
{
// Handle the error
}
}
所有这些都说......在现代系统上一次读一个角色是非常低效的。调整代码以一次读取一个缓冲区,并立即写出整个修改过的缓冲区。
答案 2 :(得分:0)
原因:
对于打开更新的文件(包含“+”符号的文件),允许进行输入和输出操作,在读取操作之前,应刷新流(fflush)或重新定位(fseek,fsetpos,rewind)这是在写作操作之后。在读取操作之后的写入操作(每当操作没有到达文件结尾)时,流应重新定位(fseek,fsetpos,rewind)。
解决方案:
你应该添加“fflush(fp);”在fwrite行之后。