在 C 語言中使用 fscanf 逐行讀取檔案
本文將介紹幾種在 C 語言中使用 fscanf
逐行讀取檔案的方法。
在 C 語言中使用 fscanf
函式逐行讀取檔案
fscanf
函式是 C 標準庫格式化輸入工具的一部分。為不同的輸入源提供了多個函式,如從 stdin
讀取的 scanf
,從字串讀取的 sscanf
,以及從 FILE
指標流讀取的 fscanf
。後者可用於逐行讀取常規檔案並將其儲存在緩衝區中。
fscanf
採取與 printf
指定器類似的格式化規範,所有的格式化規範在這個頁面上都有詳細的列出。在下面的例子中,我們使用 fopen
函式呼叫開啟樣本輸入檔案,並分配滿檔案大小的記憶體將讀流儲存到其中。"%[^\n] "
格式字串被指定為讀取檔案流,直到遇到新的行字元。fscanf
當到達輸入結束時返回 EOF
,因此我們用 while
迴圈迭代,逐行列印。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char* filename = "input.txt";
int main(int argc, char *argv[])
{
FILE *in_file = fopen(filename, "r");
struct stat sb;
stat(filename, &sb);
char *file_contents = malloc(sb.st_size);
while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
printf("> %s\n", file_contents);
}
fclose(in_file);
exit(EXIT_SUCCESS);
}
輸出:
> Temporary string to be written to file
請注意,即使前面的程式碼很可能在檔案系統中存在輸入檔名的情況下成功執行,但多次函式呼叫還是會失敗,程式異常終止。接下來的示例程式碼是修改後的版本,其中實現了錯誤檢查例程。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char* filename = "input.txt";
int main(int argc, char *argv[])
{
FILE *in_file = fopen(filename, "r");
if (!in_file) {
perror("fopen");
exit(EXIT_FAILURE);
}
struct stat sb;
if (stat(filename, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
char *file_contents = malloc(sb.st_size);
while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
printf("> %s\n", file_contents);
}
fclose(in_file);
exit(EXIT_SUCCESS);
}
輸出:
> Temporary string to be written to file
使用 fscanf
函式用 C 語言逐字讀取檔案
利用 fscanf
函式的另一個有用的例子是遍歷檔案並解析每一個空格分隔的標記。請注意,與前面的例子相比,唯一需要改變的是格式指定符為"%[^\n ] "
。stat
系統呼叫是為了檢索檔案大小,該值被用來作為 malloc
引數傳遞,以分配緩衝區。這種方法對於某些場景來說可能會很浪費,但它能保證即使是最大的單行檔案也能儲存在緩衝區中。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char* filename = "input.txt";
int main(int argc, char *argv[])
{
FILE *in_file = fopen(filename, "r");
if (!in_file) {
perror("fopen");
exit(EXIT_FAILURE);
}
struct stat sb;
if (stat(filename, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
char *file_contents = malloc(sb.st_size);
while (fscanf(in_file, "%[^\n ] ", file_contents) != EOF) {
printf("> %s\n", file_contents);
}
fclose(in_file);
exit(EXIT_SUCCESS);
}
輸出:
> Temporary
> string
> to
> be
> written
> to
> file
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn