使用 C unix 命令或 C 更改文件中的特定单词

标签 c file unix

我有一个文件,其中包含:

<Ip_Adress> <User_Id> <User_Name>

当用户想要更改他的名字时,他会指定一个新名字。该新名称应替换文件中的 。我可以通过两种方式完成此操作:使用 C 代码或使用 unix 命令。我不知道如何使用 unix 来做到这一点,但我更喜欢这个解决方案。我尝试使用 C 来实现,但出现段错误。我将粘贴代码。 (在函数中引用将更改其名称的用户的 IP 地址)

void change_name(char* ip,char* new_name){
    FILE *f1,*f2;
    //Attending to one answer I have changed the var to array but the error persists
    char buffer[30],ip_address[30],user_id[30],user_name[30];
    f1 = fopen ( "data.txt", "r" );
    f2 = fopen ( "temporal.txt", "w");

    if (f1==NULL){
        perror ("Error opening the file data.txt");
        fclose(f1);
    }

    if (f2==NULL){
        perror ("Error opening the file temporal.txt");
        fclose(f2);
    }

    while (feof(f1)==0)
    {
        fscanf(f1,"%s %s %s",ip_address,user_id,user_name);
        if(strcmp(ip,ip_address)==0){
            fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);
        }else{
            fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);
        }

    }
    fclose (f1);
    fclose (f2);
    remove(f1);
    rename("temporar.txt","data.txt");
}

data.txt 的示例如下:

100.100.1.31 af9a67fa8 Guest
200.200.1.31 a43fji462 Guest

所以问题是更改与给定的特定 IP 匹配的特定 guest

示例:IP 地址为 100.100.1.31 的用户想要将自己的名字更改为 Superman,因此 data.txt 文件将产生:

100.100.1.31 af9a67fa8 Superman
200.200.1.31 a43fji462 Guest

该命令可以工作

 sed -i 's/\(100.100.1.31 .\{9\} \)Guest/\1Superman/g' data.txt

现在的问题是使用 execlp 或其他类似命令将其传递给 C。

最佳答案

您的段错误来自于您在 fscanf 中使用的 char *。 如果您对它们进行 malloc(或将它们声明为数组),它就会起作用。

但是,我认为最好的方法是使用 sed。请参阅其他答案以了解有效的命令

编辑:您可以使用 asprintf() 简单地格式化您的 sed 正则表达式,并使用 system() 或您想要的任何派生调用它(system() 更好,它允许您执行 shell 命令而无需先 fork )。

正如我在回复您的评论时告诉您的那样,您的代码对我来说不会出现段错误。您只需将 ip_address 设置为 16(255.255.255.255 = 16 个字符)并将 user_id 设置为 9,以获得更好的内存使用率。

编辑2: 这是我修改后使其工作的代码。我添加了评论,让您知道我做了什么以及为什么这样做。

#include <stdlib.h>                                                                                                                                                   
#include <stdio.h>                                                                                                                                                    

void change_name(char* ip,char* new_name){                                                                                                                            
  FILE *f1,*f2;                                                                                                                                                       
  //Attending to one answer I have changed the var to array but the error persists                                                                                    
  char ip_address[16],user_id[9],user_name[30]; //Better memory managment                                                                                             

  f1 = fopen ( "data.txt", "r" );                                                                                                                                     
  if (f1==NULL){                                                                                                                                                      
    perror ("Error opening data.txt file");                                                                                                                           
    exit(EXIT_FAILURE); //If you can't open first file, exit. File isn't openned, so don't close it.                                                                  
  }                                                                                                                                                                   
  f2 = fopen ( "temporal.txt", "w");                                                                                                                                  
  if (f2==NULL){                                                                                                                                                      
    perror ("Error opening temporal.txt file");                                                                                                                       
    fclose(f1); //Close first file, because you openned it                                                                                                            
    exit(EXIT_FAILURE); //Then exit                                                                                                                                   
  }                                                                                                                                                                   

  while (fscanf(f1,"%s %s %s",ip_address,user_id,user_name)==3) //fscanf returns the number of args read. If not 3, there is a problem.                               
    {                                                           // Directly verify of fscanf avoids the last line double read problem                                 
      if(strcmp(ip,ip_address)==0){                                                                                                                                   
        fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);                                                                                                         
      }else{                                                                                                                                                          
        fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);                                                                                                        
      }                                                                                                                                                               
    }                                                                                                                                                                 
  remove((const char *)f1);                                                                                                                                           
  rename("temporal.txt","data.txt");                                                                                                                                  
  fclose(f1); //Close your files at end, so you will avoid problems when manipulating them                                                                            
  fclose(f2);                                                                                                                                                         
}                                                                                                                                                                     

int     main() // Simple test main                                                                                                                                    
{                                                                                                                                                                     
  change_name("100.100.1.31", "Superman");                                                                                                                            
  return (0);                                                                                                                                                         
} 

关于使用 C unix 命令或 C 更改文件中的特定单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36023777/

相关文章:

c - Int32转Epoch才能读取数据?! [C]

c - 0x600000000 的内存读取失败

php - 将 php 页面中的值发布到同一页面不起作用

c - 读取C中的结构体?

shell - 如何使用 Travis CI 环境变量 + .sh 脚本自动部署到 Github Pages?

c - 什么是?? () 中的段错误是什么意思?

c# - 设置文件中的光标位置

linux - 如何以不同用户身份运行 linux 命令列表

linux - 使用awk提取数据并计数

C - atmega328p - 我不明白出了什么问题