簡體   English   中英

為 C 編寫標准 unix 程序時“-”的命令行參數

[英]command-line argument of "−" when making standard unix programs for C

刪除C.c

#include <stdio.h>

int main(int argc, char **argv) {
    if (argc != 2) {
        int c;
        while((c = getchar()) != EOF) {
            if(c != 'c') {
                putchar(c);
            }
        }
    } else {
        for (size_t i = 0; argv[1][i] != '\0'; i++) {
            if(argv[1][i] != 'c') {
                putchar(argv[1][i]);
            }
        }
        putchar('\n');
    }
}

removeC.c 刪除文件中的每個 c,然后將其打印到標准輸出。 例如,

$ gcc -Wall removeC.c
$ ./a.out abc
ab
$ echo abc | ./a.out
ab
$ ./a.out file1
ab

假設 file1 的內容也是 'abc'

目標是讓它像標准的 Unix 工具一樣工作(但它可以不接受任何命令行選項,即“./a.out -w somefile”)。

如何處理“-”的命令行參數?

通常,Unix 實用程序將僅由-組成的參數解釋為等效於stdin如果它可以解釋為輸入文件,或者等效於stdout如果它肯定會解釋為輸出文件。

在這種情況下,如果它是一個命名文件,它將是一個輸入文件,因此它通常等效於stdin

這是 Posix 實用程序語法指南的指南 #13:

准則 13:

對於使用操作數表示要打開以進行讀取或寫入的文件的實用程序, -操作數應僅用於表示標准輸入(或從上下文中明確指定輸出文件時的標准輸出)或名為- .

您可以使用簡單的三元運算符並檢查argv[1]輕松完成此操作。 雖然這假定您沒有其他以'-'開頭的選項,但您可以使用getopt輕松調整它以適應這種情況。 這是一個非常方便的“快速而骯臟”的設置,可以靈活地從文件或stdin讀取輸入。

#include <stdio.h>

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

    int c;
    /* read from filename given as argv[1], or stdin by default or '-' */
    FILE *fp = argc > 1 && *argv[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;
    }

    /* output reading from ... */
    printf ("reading from '%s'\n", fp == stdin ? "stdin" : argv[1]);

    while ((c = fgetc (fp)) != EOF)     /* read until EOF */
        putchar (c);

    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    return 0;
}

示例輸入文件

$ cat dat/dog.txt
my dog has fleas

示例使用/輸出

從沒有'-' stdin讀取,

$ echo "my dog has fleas" | ./bin/unix_read_file_or_stdin
reading from 'stdin'
my dog has fleas

使用'-'stdin讀取,

$ echo "my dog has fleas" | ./bin/unix_read_file_or_stdin -
reading from 'stdin'
my dog has fleas

使用文件重定向從stdin讀取,

$ ./bin/unix_read_file_or_stdin <dat/dog.txt
reading from 'stdin'
my dog has fleas

從文件中讀取,

$ ./bin/unix_read_file_or_stdin dat/dog.txt
reading from 'dat/dog.txt'
my dog has fleas

這不能替代完整的getopt實現,但對於小型實用程序來說很方便。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM