我有一个文件,其中包含:
<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/