C中的fopen和fprintf没有按预期工作?

时间:2014-07-07 06:32:34

标签: c file printf fopen

我正在尝试编写一个程序,为现有的txt文件添加行号。

例如,如果文件当前是:

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循环中的那些是胡言乱语(看起来像小点,根本不像数字)

当我在fopen中使用“r +”时,整个数据被删除,我所能看到的只有(1)然后是乱码。

如果我在fopen中使用“a +”,它会从文件的末尾开始,然后写入(1)和乱码。

2 个答案:

答案 0 :(得分:5)

AFAIK你基本上不能在文件中间“插入”字节。相反,您将覆盖文件中的字节。因此,当您使用相同的文件进行读写时,您将“干扰自己”。 我建议您为写入输出创建一个临时文件,或者只写入标准输出,允许您将输出传递到合适的位置。

答案 1 :(得分: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;
}