2012-04-19 85 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; 
} 
相關問題