在 C 語言中使用檔案重定向

Jinku Hu 2021年2月28日
在 C 語言中使用檔案重定向

本文將介紹幾種在 C 語言中使用檔案重定向的方法。

使用 < 操作符重定向標準輸入

檔案重定向在基於 UNIX 的系統上一般稱為 I/O 重定向,它允許使用者重新定義標準輸入來自哪裡,或標準輸出去哪裡。< 運算子用來改變標準輸入的來源。這種方法對於從檔案內容中獲取使用者輸入並將其儲存在程式緩衝區中很有用。在這種情況下,我們利用 fgets 函式來讀取檔案的內容,直到遇到一個新行字元。當讀取到一個新的行字元時,它也會被儲存在給定的緩衝區中,之後會儲存字串終止的空位元組。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#define SIZE 1000

int main(int argc, char *argv[]) {

    char buf[SIZE];
    printf("Write input text: ");
    fgets(buf, SIZE , stdin);
    printf("%s\n", buf);

    exit(EXIT_SUCCESS);
}

示例命令:

./program < input.txt

輸出:

The first line from the input.txt file

在前面的示例程式碼中,我們分配了一個帶有硬編碼值的緩衝區。不過,使用者提供的輸入檔案可能需要更多的記憶體來儲存,我們應該實現一種自適應的方法來適應這種情況。為此,我們使用 malloc 分配動態記憶體,並將檔案總大小作為儲存檔案中第一行所需的最大數量傳遞給它。如果給定的檔案太大,而第一行又實在太短,這種方法可能會浪費太多記憶體。但是,它可以保證只要 malloc 不會失敗,系統記憶體不會耗盡,程式碼就能讀進最長的一行。

注意,我們使用 stat 系統呼叫來檢索檔案大小,但它需要輸入檔案的路徑名,如果不作為命令列引數明確貼上,就無法檢索。不過要注意的是,每一次函式呼叫都需要檢查是否成功返回,以保證 fgets 不會試圖寫入未初始化的記憶體區域,導致程式以失敗告終。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    char *buffer = NULL;
    const char *filename = NULL;
    struct stat sb;

    if (argc != 2) {
        printf("Usage: ./program filename < filename\n");
        exit(EXIT_FAILURE);
    }

    filename = argv[1];

    if (stat(filename, &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }

    buffer = malloc(sb.st_size);
    if (!buffer) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    printf("Write input text: ");
    if (fgets(buffer, sb.st_size , stdin) == NULL) {
        perror("fgets");
        exit(EXIT_FAILURE);
    }
    printf("%s\n", buffer);


    exit(EXIT_SUCCESS);
}

示例命令:

./program input.txt < input.txt

輸出:

The first line from the input.txt file
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

相關文章 - C File