0
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int c, n, E, b, s, v, t, opt, valid = 0;
char current = '\0';
char previous = '\0';
FILE *fp;

/*  -n numbers lines
 *  -E appends a dollar sign to line ends
 *  -b numbers only non-blank lines
 *  -s squeezes multiple blank lines down to 1
 *  -v displays control chars, excluding tab
 *  -t includes tab in the above
 *  -e is the same as -E and -v
 */

int setFlags(int argc, char *argv[]) {
    int op;
    while ((op = getopt(argc, argv, "nEbsvte")) != -1) {
        switch (op) {
            case 'n': {
                n = 1;
                break;
            } case 'E': {
                E = 1;
                break;
            } case 'b': {
                b = 1;
                break;
            } case 's': {
                s = 1;
                break;
            } case 'v': {
                v = 1;
                break;
            } case 't': {
                t = 1;
                break;
            } case 'e': {
                E = 1;
                v = 1;
                break;
            } case '?': {
                //fprintf(stderr, "Option `-%c` is not valid.\n", optopt);
                return EXIT_FAILURE;
            } default: {
                abort();
            }
        }
    }
    opt = optind;

    if(n == 1) {
        b = 0;
    }

    return EXIT_SUCCESS;
}

int checkFile(char *path) {
    if (access(path, R_OK) == 0) {
        return EXIT_SUCCESS;
    } else {
        fprintf(stderr, "cat: %s: %s\n", argv[i], strerror(errno));
        errno = 0;
        return EXIT_FAILURE;
    }
}

int doPrint(char *path) {
    if (strcmp(path, "stdin") == 0) {
        fp = stdin;
    } else {
        if (checkFile(path) == 1) {
            return EXIT_FAILURE;
        } else {
            fp = fopen(path, "r");
        }
    }
    while ((c = fgetc(fp)) != EOF) {
        putchar(c);
    }
    fclose(fp);
    return EXIT_SUCCESS;
}

int main (int argc, char *argv[]) {
    if (setFlags(argc, argv) == 1) {
        fprintf(stderr, "The program has terminated with an error.\n"
        "An invalid option was specified.\n");
        return EXIT_FAILURE;
    } else {
        if ((argc - opt) == 0) {
            doPrint("stdin");
        } else {
            for(int i = opt; i < argc; i++) {
                doPrint(argv[i]);
            }
        }
    }
}

我遇到了一个非常疯狂的错误,我的程序在完成写入文件内容之前在 checkFile 中输出错误行(总是在结束前进行一次聊天)。

它让我发疯,无论我将那段代码移动到哪里,它都无法按预期工作。

我敢肯定答案可能是微不足道的,但它让我难住了。我什至在输出完成之前投入了睡眠和其他各种事情,它会抛出错误,然后睡眠,然后打印最后一个字符。

有什么帮助吗?

4

1 回答 1

2

使用时printfstdout默认情况下会缓冲输出。这意味着它可以与其他输出交错,通常来自stderr. stderr默认情况下是无缓冲的,以便在发生错误时立即打印输出。

可以通过明智地使用fflush或关闭文件缓冲stdout来修复交错setbuf。请务必阅读 setbuf 的手册页,因为有一些警告。

在这种情况下,在 doPrint 函数末尾添加 fflush(stdout) 应该可以解决“问题”。

于 2013-03-12T06:19:22.653 回答