2014-07-07 23 views
1

我正在嘗試編寫一個程序,將行號添加到已存在的txt文件中。C中fopen和fprintf沒有按預期工作?

例如,如果該文件是當前:

Hello 
this is 
an 
exercise 

然後運行該代碼之後,這將是:

(1) Hello 
(2) this is 
(3) an 
(4) exercise 

我寫了這個代碼:

#include<stdio.h> 
#include<conio.h> 
FILE *fp; 
void main() 
{ 
    int counter=1; 
    char newline; 
    fp=fopen("G:\\name.txt","r+"); 
    if(fp==NULL) 
     printf("Failed to open file!"); 
    fprintf(fp,"(%d)",counter); 
    newline=fgetc(fp); 
    while(newline!=EOF) 
    { 
     if(newline=='\n') 
     { 
      counter++; 
      fprintf(fp,"(%d)",counter); 
     } 
     newline=fgetc(fp); 
    } 
    printf("All done!"); 
    getch(); 
    fclose(fp); 
} 

而且輸出很奇怪。

首先,它不打印在文件的開頭。出於某種原因,它從文件的末尾開始。而另一個奇怪的事情是,只有第一次印刷成功。

while循環中的那些都是胡言亂語(看起來像小圓點,都不會像數字)

當我使用「R +」則fopen內,整個數據被刪除,和所有我能看看是(1)然後亂碼。

如果我在fopen中使用「a +」,它會從文件末尾開始,然後寫入(1)和亂碼。

+0

不是你的主要問題,但'fgetc'返回'int',使用'newline'作爲'char'會給你帶來意想不到的結果。 –

回答

5

AFAIK你基本上不能在文件中間插入字節。相反,您將覆蓋文件中的字節。因此,當你使用相同的文件進行閱讀和寫作時,你會「干涉自己」。 我建議你爲寫入的輸出創建一個臨時文件,或者寫入標準輸出,以便將輸出傳送到合適的位置。

0

這裏是我的建議:

#include <stdio.h> 
// None conio.h 
// Not global variable fp 

#include <stdlib.h> // To use exit() 

void handle_error(char* message); 
int is_a10power(int n); 

int main(void) // Standard form of main() 
{ 
    FILE *fp1 = fopen("G:\\name.txt","r"); // 1st file open for reading only 
    if (fp1 == NULL) 
     handle_error("Error open file for reading\n"); 
    FILE *fp2 = fopen("G:\\name2.txt","w"); // 2nd file open for writting only 
    if (fp1 == NULL) 
     handle_error("Error open file for writting\n"); 

    int io_result; 

    char c = '\n';  // The name "newline" is not adequate: changed by "c" 
    int counter = 0; // Start in 0 because increment will be done at the beginning 
    int no_digits = 0; // Number of digits of "counter" 

    for(;;) // Loop 
    { 
     if (c == '\n') // End-of-line handling 
     { 
      counter++; 
      if (is_a10power(counter)) 
       no_digits++; 

      io_result = fprintf(fp2,"(%d) ", counter); 
      if (io_result < 3 + no_digits) // Error: not all bytes could be written to fp2 
      handle_error("Cannot write file\n"); 
     } 

     c = fgetc(fp1); // Reads only 1 character from fp1 
     if (ferror(fp1)) 
       handle_error("Cannot read file\n"); 

     if (c == EOF) 
       break; // <--------- Loop exits here 

     io_result = fprintf(fp2,"%c", c); 
     if (io_result < 1) // Less than 1 bytes transmited implies "fail" 
       handle_error("Cannot write file\n"); 
    } 

    io_result = fclose(fp1); 
    if (io_result == EOF) 
     handle_error("Close file error\n"); 
    io_result = fclose(fp2); 
    if (io_result == EOF) 
     handle_error("Close file error\n"); 

    printf("All done!"); // The success message goes after all operations are finished 
    getchar(); // I like more getchar() than getch() 
    return 0; // Success 
} 

void handle_error(char* message) 
{ 
    printf("%s",message); 
    exit(EXIT_FAILURE); // If error, end the program 
} 

int is_a10power(int n) 
{ 
    while (n % 10 == 0) 
     n /= 10; 
    return (n == 1); 
} 

看來我迷戀與I/O錯誤。
因此,另一種風格可能是以下幾點:

#include <stdio.h> 
#include <stdlib.h> // To use exit() 

FILE* safe_fopen(const char restrict * filename, const char restrict * mode); 
void safe_fclose(FILE* F); 
void safe_fprintf_int(FILE* F, int n); 
void safe_fprintf_char(FILE* F, char c); 
int safe_fgetc(FILE* F); 

void handle_error(char* message); 

int main(void) 
{ 
    FILE *fp1 = safe_fopen("G:\\name.txt","r"); // 1st file open for reading only 
    FILE *fp2 = safe_fopen("G:\\name2.txt","w"); // 2nd file open for writting only 

    char c = '\n'; 
    int counter = 0; 
    for(;;) // Loop 
    { 
     if (c == '\n') 
      safe_fprintf_int(fp2, ++counter); // End-of-line handling 
     c = safe_fgetc(fp1); 
     if (c == EOF) 
      break; // <--------- Loop exits here 
     safe_fprintf_char(fp2, c); 
    } 
    safe_fclose(fp1); 
    safe_fclose(fp2);   
    printf("All done!"); 
    return 0; 
} 

void handle_error(char* message) 
{ 
    printf("%s",message); 
    exit(EXIT_FAILURE); // If error, end the program 
} 


FILE* safe_fopen(const char restrict * filename, const char restrict * mode) 
{ 
    FILE* F = fopen(filename, mode); 
    if (F == NULL) 
     handle_error("Cannot open file"); 
    else 
     return F; 
} 
void safe_fclose(FILE* F) 
{ 
    if (fclose(F) == EOF) 
     handle_error("Error closing file"); 
} 

int no_digits(int n) 
{ 
    int nod = 0; 
    for (; n != 0; n /= 10) 
     nod++; 
    return nod; 
} 

void safe_fprintf_int(FILE* F, int n) 
{ 
    if (fprintf(F,"(%d) ",n) < 3 + no_digits(n)) 
     handle_error("Error writting digits to file"); 
} 

void safe_fprintf_char(FILE* F, char c) 
{ 
    if (fprintf(F,"%c",c) < 1) 
     handle_error("Cannot write character in file"); 
} 

int safe_fgetc(FILE* F) 
{ 
    int r = fgetc(F); 
    if (ferror(F)) 
     handle_error("Cannot read file"); 
    else 
     return r; 
}