3

我一直在尝试同时读取和写入文件,并且尝试将 text.txt 内容中的所有选项卡替换为空格。这是我的代码:

int main()
{
   FILE* filePtr = fopen("text.txt", "w+");

   char c;
   c = fgetc(filePtr);
   fpos_t num;
   while(c != EOF)
   {
       if(c == '\t')
       {
           fgetpos(filePtr, &num);
           num--;
           fsetpos(filePtr, &num);
           fputc(' ', filePtr);
       }
       c = fgetc(filePtr);
   }
}

text.txt 的内容是这样的:

嗨 \t 我的 \t 名字 \t 是 \t 杰克!

当我运行这段代码时,我在 text.txt 文件中的输出只是空白。那里没有字符。我应该怎么做才能使替换按预期进行?

4

4 回答 4

8

您的代码存在三个主要问题:

  1. 使用模式打开文件会"w+" 截断文件(删除所有内容)。您可以对其进行读写,但原始内容会丢失。模式"r+"将在不更改内容的情况下打开它进行读取和写入,并且文件位置最初位于文件的开头。

  2. 对 type 的值执行算术运算是不安全的fpos_t。反正没必要;有一种更简单的方法可以将文件位置移动一个相对量。

  3. 完成后不要关闭文件。

您的代码的这种变化对我有用:

#include <stdio.h>

int main(void)
{
   FILE* filePtr = fopen("text.txt", "r+");
   char c;

   while((c = fgetc(filePtr)) != EOF)
   {
       if(c == '\t')
       {
           fseek(filePtr, -1, SEEK_CUR);
           fputc(' ', filePtr);
       }
   }
   fclose(filePtr);
   return 0;
}
于 2015-04-16T14:58:19.907 回答
2

引用cplusplus.com

"w+" 写入/更新:创建一个空文件并打开它进行更新(输入和输出)。如果已存在同名文件,则丢弃其内容并将该文件视为新的空文件。

您应该使用“r+”。

"r+" 读取/更新:打开一个文件进行更新(输入和输出)。该文件必须存在。

于 2015-04-16T14:32:23.240 回答
1

这里的代码有两个主要问题:

  1. 此处必须使用“r+”模式而不是“w+”。

“w+”模式会删除文件的所有内容,如果它从之前退出然后写入文件,而“r+”模式允许您使用之前的当前数据。

  1. 当从读取到写入或从写入到读取数据切换时,必须使用位置设置功能。

来自 Pelles C 帮助文件:

当以更新模式(模式参数中的第二个或第三个字符为“+”)打开文件时,可以在关联的流上执行输入和输出。但是,如果没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的干预调用,则输出不应直接跟随输入,并且在没有对文件定位的干预调用的情况下,输入不应直接跟随输出函数,除非输入操作遇到文件结尾。

这是对我有用的代码:

int main(void)
{
    FILE* filePtr = fopen("text.txt", "r+");
    char c;
    while( (c = fgetc(filePtr)) != EOF )
    {
        if(c == '\t')
        {
            fseek(filePtr, -1, SEEK_CUR);
            fputc(' ', filePtr);
            fseek(filePtr, 0, SEEK_CUR);
        }
    }

    fclose(filePtr)
    return 0;
}
于 2015-04-18T15:19:09.610 回答
0

问题是您正在使用w+fopen 标志并试图减少fpos_t复杂类型的变量。您应该使用r+然后递减num.__pos以使其正常工作

于 2015-04-16T14:40:40.887 回答