我正在尝试编写一个程序,为现有的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)和乱码。
答案 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;
}