fgets 和 fscanf 對換行符的處理
fscanf
int fscanf ( FILE * stream, const char * format, ... );
fscanf 將讀取並忽略在下一個非空白字符之前遇到的任何空白字符(空白字符包括空格、換行符和制表符)。
fscanf 讀取字符串時,讀取任意數量的非空白字符,在找到的第一個空白字符處停止。在存儲序列的末尾自動添加終止空字符。
fgets
char * fgets ( char * str, int num, FILE * stream );
換行符使 fgets 停止讀取,但它被函數視為有效字符並包含在復制到 str 的字符串中。
fgets 只能讀取 num - 1 個字符,包括最后的換行符,在復制到 str 的字符后自動附加終止空字符。
驗證實例
總之,fscanf 不會讀取換行符,讀取之前會跳過所有換行符,讀到換行符停止(流中的換行符還在)。
fgets 讀取一行,讀到換行符為止,但會讀掉換行符(流中的換行符沒有了)。
因此,如果使用了 fscanf 讀取一行的內容,流中會剩余一個換行符,再使用 fgets 只會讀到這個剩余的換行符,不會讀取下一行。需要再使用 fgets 才能讀取下一行。
#include <stdio.h>
int main() {
FILE *fp = fopen("test.txt", "r");
char line[20];
int a, b, c;
fscanf(fp, "%d %d %s", &a, &b, line);
fprintf(stdout, "%s", line); // String1
fgets(line, 20, fp);
fprintf(stdout, "%s\n", line); // '\n'
fgets(line, 20, fp);
fprintf(stdout, "%s", line); // String2
}
[qhn@Tommy C_Prog]$ ./a
String1
String2
Breakpoint 1, main () at test.c:12
12 printf("%s", line); // '\n'
(gdb) print(line)
$1 = "\n\000ring1\000@\005@\000\000\000\000\000\340\340\377\377"
12 行不打印任何字符的原因參考 C編程中printf不加'\n'不輸出。