C函数用于在文件中的特定位置插入文本而不会覆盖现有文本

Rah*_*hul 15 c file-io

我编写了一个程序,它接受一个文件作为输入,每当它找到一个长度> 80的行时,它会将\和\n添加到该文件中,使其最大宽度为80个字符.

问题是我已经使用fseek插入\和\n,只要长度超过80,所以它会覆盖超过长度80的那一行的两个字符.有没有一种方法可以插入文本而不覆盖现有文本?

这是我的代码: -

#include<stdio.h>
#include<string.h>

int main(int argc, char *argv[])
{
  FILE *fp1,*fp2;
  int prev=0,now=0;
  char ch;
  int flag=0;
  long cur;
  fp1=fopen(argv[1],"r+");
  if(fp1==NULL){
    printf("Unable to open the file to read. Program will exit.");
    exit(0);
  }
  else{
    while((ch=fgetc(fp1))!=EOF){
      if(ch!=' ' && ch!='\n'){
        now=now+1;
      }
      else{
        if(now>=80){
            fseek(fp1,cur,SEEK_SET);
            fputc('\\',fp1);
            fputc('\n',fp1);
            now=0;
            continue;
        }
        if(ch=='\n'){
          flag=0;
          now=0;
          continue;
          }
        else{
          prev=now;
          cur=ftell(fp1);
        }
        now=now+1;
      }
    }
  }
  fclose(fp1);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

要运行它,您需要执行以下操作: -

user@ubuntu$ cc xyz.c
user@ubuntu$ ./a.out file_to_check.txt
Run Code Online (Sandbox Code Playgroud)

Pav*_*rda 17

虽然有几种技术可以就地完成,但您正在处理文本文件并希望执行插入操作.操作系统通常不支持将文本文件插入作为文件系统原语,并且他们没有理由这样做.

执行此类操作的最佳方法是打开文件进行读取,打开新文件进行写入,在插入点之前复制文件的一部分,插入数据,复制其余文件,然后将新文件移到旧的.

这是一种常见的技术,它有一个目的.如果出现任何问题(例如使用您的系统),您仍然拥有原始文件,并且可以稍后重复该事务.如果启动该进程的两个实例并使用特定模式,则第二个实例能够检测到该事务已经启动.通过独占文件访问,它甚至可以检测事务是否被中断或仍在运行.

这种方式比直接在原始文件上执行的任何技术都更不容易出错,并且被所有这些传统工具使用,sed即使您要求它们就地工作(sed -i).另一个好处是,您可以在覆盖之前始终将原始文件重命名为具有备份后缀的文件(也sed提供此类选项).

即使您的程序正在编写一个全新的版本并且不使用原始文件,相同的技术也经常用于配置文件.很久以来,很多互联网杂志声称ext4意外地将配置文件截断为零长度.这正是因为某些应用程序在强制关闭系统时保持配置文件打开和截断.这些应用程序准备好数据之前经常会篡改原始配置文件,然后甚至在不同步它们的情况下保持打开状态,这使得数据损坏的窗口大得多.

TL; DR版本:

当您重视数据时,请不要在准备好替换数据之前将其销毁.


NPE*_*NPE 8

不,没有办法将字符插入现有文件中.您将需要使用第二个文件来执行此操作.

  • 您只需要插入的字节数就可以了; 这是必须提前读取多少才允许插入数据而不破坏它. (3认同)
  • 尾巴不必适合记忆.你可以寻找到最后并从最后向后移动角色.如果你不关心它在病理上慢,那么单字符缓冲就足够了.实际上,你需要一个至少几KB的缓冲区,但你绝对不需要将整个尾部存储在内存中. (2认同)