2012-04-19 83 views
1

我有一个txt文件是这样的:编辑的特定行中的文件

"shoes":12 
"pants":33 
"jacket":26 
"glasses":16 
"t-shirt":182 

我需要编辑护套(从26至42,例如)的数量。 所以,我写了这个代码,但我不知道如何编辑特定的行那里是单词“外套”:

#include <stdio.h> 

int main() { 
    char row[256]; 
    FILE *fp; 

    if (!(fp=fopen("myfile.txt","rw"))) { 
     printf("Error"); 
     return 1; 
    } 

    while (!feof(fp)){ 
     fgets(row, 256, fp); 
     // if there is the "jacket" in this row, then edit the row 
    } 

    fclose (fp); 
    return 0; 
} 

回答

5

不幸的是没有简单的解决了这一点。

一种常见的方法是将所有行(已修改或未已写入)写入临时文件,然后将临时文件移至现有文件上。

+0

在C++中是否有最简单的解决方案? – xRobot 2012-04-19 10:02:20

+0

@xRobot语言无所谓,问题和解决方案是一样的。 – 2012-04-19 10:09:39

+0

为什么我们不能在“r +”模式下打开文件并使用'ftell','fseek'组合并覆盖文件? – 2012-04-19 10:13:47

0

文本文件不是像数据库那样我们可以在一个镜头中修改单个行或列,这在c/C++中也很难,它是以重复编码为代价的。

0

编写脚本并使用sed(流编辑器)编辑特定的流。

4

如果新旧值的字符数是相同的(你的情况),您可以覆盖它们:

FILE* fp = fopen("x.txt", "r+"); // note: r+, not rw 
char row[256]; 
char* string = "\"jacket\":"; // note: contains punctuation 
char* newvalue = "42\n"; // note: contains a line break 

while (!feof(fp)) // note: feof is bad style 
{ 
    long pos = ftell(fp); 
    fgets(row, 256, fp); // note: might add error handling 

    // check if there is the "jacket": in this row, 
    if (strncmp(row, string, strlen(string)) == 0) 
    { 
     // check that the old length is exactly the same as the new length 
     // note: assumes the row contains a line-break \n 
     if (strlen(row) == strlen(string) + strlen(newvalue)) 
     { 
      // then edit the row 
      fseek(fp, (long)(pos + strlen(string)), SEEK_SET); 
      fputs(newvalue, fp); 
      fseek(fp, (long)(pos + strlen(string) + strlen(newvalue)), SEEK_SET); 
     } 
     else 
     { 
      printf("Too bad, cannot change value"); 
     } 
    } 
} 
fclose(fp); 

你可能想改变你的文件格式,包括填充,例如:

"shoes":12____ 
"pants":33____ 
"jacket":26____ 
"glasses":16____ 
"t-shirt":182___ 

这里_可视化空间字符;这种文件格式最多支持999999项。如果你做了这样的改变,你需要改变上面的代码来检查和调整空格的数量等。

0

它可能更容易使用gawk。

gawk -f edit_row.awk <myfile.txt >tmp.txt && mv tmp.txt myfile.txt 

edit_row.awk

BEGIN { 
    FS = ":" 
} 

{ 
    if ($1 == "\"jacket\"") { 
     print $1 ":" 42 
    } else { 
     print 
    } 
} 

如果你真的想这样做在C您可以使用TMPFILE()函数。

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

int main() { 
    char row[256]; 
    char *file_name = "myfile.txt"; 
    FILE *file_pointer; 
    FILE *temp_file; 

    char col_a[101] = ""; 
    unsigned int col_b = 0; 
    char filter[] = "\"jacket\""; 
    size_t filter_length = sizeof(filter) - 1; 

    file_pointer=fopen(file_name,"r+"); 
    temp_file=tmpfile(); 

    while (fgets(row, 256, file_pointer) != NULL) { 
     if (strncmp(row, filter, filter_length) == 0) { 
      fprintf(temp_file,"%s:46\n", filter); 
     } else { 
      fprintf(temp_file, "%s", row); 
     } 
    } 


    rewind(temp_file); 
    rewind(file_pointer); 

    while (fgets(row, 256, temp_file) != NULL) { 
     fputs(row, file_pointer); 
    }; 

    fclose(file_pointer); 
    fclose(temp_file); 
    return 0; 
} 
相关问题