同时写入和读取文件

问题描述 投票:0回答:4

我一直在尝试同时从文件中读取和写入,并且尝试将 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的内容是这样的:

嗨,我的名字是杰克!

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

c file readfile writefile
4个回答
8
投票

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

  1. 使用模式打开文件

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

  2. fpos_t
    类型的值执行算术运算是不安全的。无论如何,这是没有必要的;有一种更简单的方法可以将文件位置移动相对量。

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

以及至少两个次要问题:

  1. fgetc()
    返回
    int
    ,而不是
    char
    ,其值在
    unsigned char
    范围内,加上
    EOF
    ,保证在该范围之外。如果将结果转换为
    char
    ,那么最多只会有一个真实的字符值,您无法将其与
    EOF
    区分开来。

  2. 为了更优雅的失败行为,您应该检查

    fopen()
    的返回值以验证其是否成功,如果未成功则进行相应处理。 (下面不演示。)

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

#include <stdio.h>

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

   while((c = fgetc(filePtr)) != EOF)
   {
       if(c == '\t')
       {
           fseek(filePtr, -1, SEEK_CUR);
           fputc(' ', filePtr);
       }
   }
   fclose(filePtr);
   return 0;
}

2
投票

引用cplusplus.com

“w+”写入/更新:创建一个空文件并打开它进行更新(两者 用于输入和输出)。如果同名文件已经存在 内容将被丢弃,文件将被视为新的空文件。

你应该使用“r+”。

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


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;
}

0
投票

问题是您正在使用

w+
fopen 标志并尝试减少复杂类型的
fpos_t
变量。您应该使用
r+
,然后递减
num.__pos
才能使其正常工作

© www.soinside.com 2019 - 2024. All rights reserved.