简单的C程序逐行读取文件

我想要做的是读取文件的第一行,但是在第一行之后只读取以下行,直到命中空格。 我的最终目标是通过向所述行添加/减去时间来询问用户他们想要编辑哪行。

示例文件

My test file 00:19.1 123456 00:35.4 testing whitespace end 

期望的输出

 1: My test file 2: 00:19.1 3: 00:35.4 

码:

 #include  #include  int main() { FILE *fptr1, *fptr2; char filechar[40]; char c[50]; int line_number = 1; int replace_line, temp = 1; printf("Please enter a file name: "); scanf("%s", &filechar); if ((fptr1 = fopen(filechar, "r")) == NULL) { printf("Error locating desired file"); exit(1); } c = getc(fptr1); while (c != EOF) { //printf("%d: %c",line_number, c); printf("%s",c); c = getc(fptr1); //line_number++; } return 0; } 

在C中你有面向字符的输入函数(例如getcharfgetc ),你有格式化的输入函数(例如scanf系列),然后你有面向行的输入函数。 (例如fgets和POSIX getline )。 在读取数据行时,面向行的输入函数是适合该作业的工具。 (用scanf接受用户输入有很多陷阱,新的(甚至不是那么新的)C程序员都会陷入困境)

所有面向行的函数都读取并在它们填充的缓冲区中包含 '\n' 。 如果稍后将在您的代码中使用,您可以而且应该从结果缓冲区中删除换行符。 一个简单的

 size_t n = strlen (buf); if (buf[n-1] == '\n') buf[--n] = 0; 

是你需要用nul-terminating字符覆盖尾部'\n' 。 如果您只是立即打印该行而不是存储它以供以后使用,那么不值得删除换行符(只需在输出格式字符串中对其进行说明 )。

将这些部分组合在一起,您可以读取每一行,只需输出它就可以处理第一行,并且对于每个剩余行,从fgets使用sscanf读取的完整字符串中解析时间(可能需要一些经过的时间 )并按指定格式化输出。 例如

 #include  #define MAXC 64 /* define constants, don't use magic number in code */ int main (int argc, char **argv) { char buf[MAXC] = ""; /* buffer to hold each line -- size as reqd */ int line = 1; FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; if (!fp) { /* validate file open for reading */ fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); return 1; } while (fgets (buf, sizeof buf, fp)) { /* read each line in file */ char et[MAXC] = ""; /* buffer for holding time */ if (line == 1) /* if 1st line, just print */ printf ("%d : %s", line, buf); /* note: \n included by fgets */ else { if (sscanf (buf, "%s", et) != 1) { /* parse up to first whitespace */ fprintf (stderr, "error: invalid conversion, line %d\n", line); return 1; } printf ("%d : %s\n", line, et); /* output elapsed time only */ } line++; /* increment line count */ } if (fp != stdin) fclose (fp); /* close file if not stdin */ return 0; } 

注意:你应该通过在sscanf格式字符串中包含字段宽度说明符来防止缓冲区溢出(例如sscanf (buf, "%63s", et) ,这是你可以做的所有事情包括幻数在你的代码中,因为没有办法直接为sscanf指定一个可变宽度说明符 – 除非你创造性地使用sprintf提前创建格式字符串 – 但这是另一天…

示例输入文件

 $ cat dat/et.txt My test file 00:19.1 123456 00:35.4 testing whitespace end 

示例使用/输出

 $ ./bin/et  

仔细看看,如果您有任何其他问题,请告诉我。

(注意:我将文件名作为程序的第一个参数,或者如果没有给出文件名则从stdin读取.C提供命令行参数 - 使用它们。如果需要,可以提示输入,否则,它更容易只是在命令行上指定参数:)

请尝试此C代码可以帮助您。 它只是逐行读取文件,并用字符串终止字符\0替换空格。

 #define _GNU_SOURCE #include  #include  #include  char* replace_char(char* str, char find, char replace){ char *current_pos = strchr(str,find); while (current_pos){ *current_pos = replace; current_pos = strchr(current_pos,find); } return str; } int main(void) { FILE * fp; char * line = NULL; size_t len = 0; ssize_t read; fp = fopen("/home/developer/CLionProjects/untitled4/download.out", "r"); if (fp == NULL) exit(EXIT_FAILURE); int count=0; while ((read = getline(&line, &len, fp)) != -1) { if (count==0) printf("%s", line); else printf("%s\n", replace_char(line, ' ', '\0')); count++; } fclose(fp); if (line) free(line); exit(EXIT_SUCCESS); } 

文件

 My test file 00:19.1 123456 00:35.4 testing whitespace end 

产量

 My test file 00:19.1 00:35.4