C语言文件操作问题,怎样替换文件中一行数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言文件操作问题,怎样替换文件中一行数据相关的知识,希望对你有一定的参考价值。

例如:一个txt文件
i have a dream;
i want to be a bird;
that‘s all;

把第二行换成: good morning;

给我代码 谢谢!!!

  C语言提供了文件操作,但是替换文件的某一行比较麻烦,下面一个参考方法,文件中存贮的内容如下所示:

  通过使用下面的几个函数,fopen,fprintf,fscanf,fseek,ftell 。具体的函数函数原型如下所示:

  FILE*fopen(const char*filename,const char *mode);

  int fprintf(FILE*stream,const char *format,...)

  int fscanf(FILE* stream,const char *format,...)

  int fseek(FILE*stream,long offset,int origin)

  long ftell(FILE* stream)

  首先,数据写入到文件中的是追加的形式。具体的写入代码如下所示:

  主要写入时要指定每个数据的宽度,若不指定,当修改某行的数据,修改后的长度大于修改前得长度,将影响文件中的下一行。制定宽度之后,只要修改后的长度不大于制定的宽度,都不影响下面的内容。(这是注意点)

FILE *fp=fopen("clientinfo.txt","ar+");

Clientinfo info;

memset(&info,0,sizeof(Clientinfo));

。。。。

。。。。/*完成对info结构体的赋值*/

fprintf(fp,"%10s %10s %10d %10s %10s %10s %10d %10d",info.id,info.nickname,\\

info.online,info.pwd,info.encryp,info.ip,info.port,info.fd);

fprintf(fp,"\\n");

fclose(fp);

修改处的代码如下所示,整个代码是在MFC中实现的:

FILE *fp=fopen("clientinfo.txt","r+");

Clientinfo info;

long nline=0,n;

memset(&info,0,sizeof(Clientinfo));

int oldline=0;/*记录匹配位置的前一行的偏移量*/

CString str;

while((n=fscanf(fp,"%s %s %d %s %s %s %d %d",info.id,info.nickname,\\

&info.online,info.pwd,info.encryp,info.ip,&info.port,&info.fd))!=EOF)

      str.Format("%d",nline);

      MessageBox(str);

      if(strncmp(info.id,id,id.GetLength())==0)/*查找要修改的位置*/

     

oldline=nline;

 break;

     

      nline=ftell(fp);


fseek(fp,oldline,SEEK_SET);/*定位到要修改的位置,注意,这个位置是上一次读的最后,故写的时候要先写换行,第一行除外*/

    if(oldline!=0)

   

     fprintf(fp,"\\n");

   

    fprintf(fp,"%10s %10s %10d %10s %10s %10s %10d %10d",info.id,info.nickname,\\

        info.online,info.pwd,info.encryp,info.ip,info.port,info.fd);

    fprintf(fp,"\\n");

    fclose(fp);


下面是修改后的数据,修改第二行,没有影响前后的数据。  

参考技术A #include <stdio.h>
#include <stdlib.h>

#define N 512 //一行中最大字符数

int main()

char filename[] = "test.txt"; //原文件名
char* tmpname = NULL; //临时新文件名
FILE* fpOri = NULL; //指向原文件
FILE* fpNew = NULL; //指向新文件
char buf[N];

//打开原文件
fpOri = fopen(filename, "r");
if (fpOri == NULL)
printf("Error: Cannot open original file!\n");
exit(1);


//生成新文件名并打开临时新文件
tmpname = tmpnam(tmpname);
fpNew = fopen(tmpname, "w");
if (fpNew == NULL)
printf("Error: Cannot open tmp file!\n");
exit(1);


//第一行
fgets(buf, N, fpOri);
fputs(buf, fpNew);
//第二行
fgets(buf, N, fpOri);
fprintf(fpNew, "good morning;\n");
//第三行
fgets(buf, N, fpOri);
fputs(buf, fpNew);

//关闭文件
fclose(fpOri);
fclose(fpNew);

remove(filename); //删除原文件
rename(tmpname, filename); //重命名新文件

return 0;
追问

谢谢啊 !!但是目标文件是cpp文件,想把其中的所有scanf和printf都换成fscanf fprintf即把从键盘获取换成从文件中提取,要怎么做才能有效率的实现呢??

追答

用编辑器查找替换。

追问

呃~~什么编辑器?不是很理解 VC?

追答

什么编辑器都可以,记事本也行的。

本回答被提问者采纳

C 语言文件操作 ( 配置文件读写 | 读取配置文件 | 函数接口形参 | 读取配置文件的逐行遍历操作 | 读取一行文本 | 查找字符 | 删除字符串前后空格 )





一、函数接口形参



函数作用 :char *filename 文件中 , 查找 char *key 关键字 对应的 值 ; 将查找到的值 写出到 char *value 指针指向的内存中 , 将值的长度写出到 int *value_len 指向的内存中 ;


代码示例 :

/**
 * @brief read_config_file 读取配置文件
 * @param filename 文件名
 * @param key      键
 * @param value    值
 * @param value_len 值字符串长度
 * @return
 */
int read_config_file(char *filename /*in*/, char *key /*in*/, char *value/*in out*/, int *value_len /*out*/)




二、读取配置文件的逐行遍历操作




1、读取配置文件的逐行遍历操作


读取配置文件的逐行遍历操作 :

  • 读取一行文本数据
  • 先判断该行数据中, 是否包含 ‘=’ 字符
  • 然后查找该行数据中 , 是否存在 Key 关键字字符串
  • 如果存在 Key 关键字 , 则继续查找 Key 关键字右侧是否有 ‘=’ 字符
  • 如果找到了 ‘=’ 字符 , 则越过该字符 , 剩下的就是 Value 字符串信息 ;
  • 删除 Value 字符串左右两侧的空格信息
  • 使用两个指针分别指向 Value 字符串两侧 ;

2、读取一行数据


        // 获取一行数据
        fgets(line_buffer, MAX_LINE, fp);

3、查找字符


        // 查找 '=' 字符
        p = strchr(line_buffer, '=');
        // 如果没有找到 '=' 字符 , 则退出 , 继续执行下一次循环
        if (p == NULL)
        
            continue;
        

4、删除字符串前后的空格


        // 获取 Value 起始位置
        for(;;)
        
            // 去掉开始位置的空格
            if (*p == ' ')
            
                p ++ ;
            
            else
            
                start = p;
                if (*start == '\\n')
                
                    // 进入到该分支 , 说明 Value 值是空的
                    // 直接退出即可
                    goto End;
                
                break;
            
        

        // 获取 Value 结束位置
        // 从 Value 的不为空格的位置开始遍历
        for(;;)
        
            // 遇到空格或回车 , 说明读取到了最后的位置, 或者换行位置
            if ((*p == ' ' || *p == '\\n'))
            
                break;
            
            else
            
                p ++;
            
        
        end = p;

5、完整代码示例


    // 逐行遍历 配置文件 中的文本数据
    while (!feof(fp))
    
        // 清空 line_buffer 中的遗留数据 , 避免被上一次写入的数据干扰
        memset(line_buffer, 0, sizeof(line_buffer));

        // 获取一行数据
        fgets(line_buffer, MAX_LINE, fp);

        // 查找 '=' 字符
        p = strchr(line_buffer, '=');
        // 如果没有找到 '=' 字符 , 则退出 , 继续执行下一次循环
        if (p == NULL)
        
            continue;
        

        // 查找 Key 值
        // 如果找到了 Key 关键字 , 则返回的指针 p 指向 Key 关键字出现的首地址中
        p = strstr(line_buffer, key);
        // 如果没有找到 Key 关键字 , 退出执行下一次循环换
        if (p == NULL)
        
            continue;
        

        // 越过 Key 关键字 , 从 Key 关键字后面的内容遍历
        p = p + strlen(key);

        // 查找 '=' 字符
        p = strchr(p, '=');
         // 如果没有找到 '=' 字符 , 则退出 , 继续执行下一次循环
        if (p == NULL)
        
            continue;
        

        // 越过 '=' 字符 , 从 '=' 字符 后面的内容遍历
        p = p + 1;

        // 获取 Value 起始位置
        for(;;)
        
            // 去掉开始位置的空格
            if (*p == ' ')
            
                p ++ ;
            
            else
            
                start = p;
                if (*start == '\\n')
                
                    // 进入到该分支 , 说明 Value 值是空的
                    // 直接退出即可
                    goto End;
                
                break;
            
        

        // 获取 Value 结束位置
        // 从 Value 的不为空格的位置开始遍历
        for(;;)
        
            // 遇到空格或回车 , 说明读取到了最后的位置, 或者换行位置
            if ((*p == ' ' || *p == '\\n'))
            
                break;
            
            else
            
                p ++;
            
        
        end = p;

        // 通过 间接赋值 设置 Value 值长度
        *value_len = end - start;

        // 通过 间接赋值 设置 Value 值数据内容
        memcpy(value, start, end - start);
    

以上是关于C语言文件操作问题,怎样替换文件中一行数据的主要内容,如果未能解决你的问题,请参考以下文章

在shell编程中,怎样对每一行每一列的数据进行操作?

C语言数据读取

C语言怎样对文件进行操作

怎么用C语言对文件操作用特定内容替换其中某些内容

C语言怎样将数字从文件里逐个读取出来

C语言文件操作为啥这个文件读取进入死循环了?