如何从终端读取C中的文件?

时间:2018-01-24 02:26:01

标签: c terminal scanf fopen

我已经读过我可以使用fopen逐行读取文件,但我想从终端访问该文件。 这就是我的尝试:

$ ./myprogram < input.txt > output.txt

我不确定是否有办法用scanf或其他方式做到这一点?

3 个答案:

答案 0 :(得分:1)

在这里,如果您考虑自己在做什么,只需从stdin继续阅读并将相同的字节写入stdout,直到收到EOF为止。虽然您可以使用面向字符的方法(例如getchar),但使用固定长度缓冲区的读取将大大减少您的读写次数。

只需声明一个大小合适的缓冲区1024(或使用默认的BUFSIZ,一般在Linux上为8192,在windoze上为512。然后重复调用fgets一次读取一个符号缓冲区的缓冲区,然后用stdout将它们写回fputs。这很简单。

#include <stdio.h>

#define BUFSZ 1024

int main (void) {

    char buf[BUFSZ] = "";

    while (fgets (buf, BUFSZ, stdin))
        fputs (buf, stdout);

    return 0;
}

理想情况下,您希望缓冲区大小比最长的行长,但它的大小无关紧要。您可以一次阅读每一行,也可以多次调用fgets。唯一的区别是所进行的函数调用次数。

答案 1 :(得分:0)

    #include <stdio.h>

    #define BUFSIZE 1024

    int main(int argc, char *argv[])    
    {
        char *line = (char *)malloc(BUFSIZE);
        if (!line)
        {
            printf("malloc buffer failed...\n");
            return 1;
        }
        memset(line, 0, sizeof(line));
        FILE *fp;
        FILE *writefp;
        int c;
        int count = 0;
        int count_buf = BUFSIZE;
        char scanf_answer;

        if (argc != 3)
        {
            printf("./myprogram <input.txt> output.txt\n");
            return 1;
        }
        fp = fopen(argv[1], "r");

        for (;;)
        {
            c = getc(fp);
            if (c == '\n')
            {
                printf("%s\n", line);
                printf("<Did you want to write this line to [%s]?>", argv[2]);
                scanf("%c", &scanf_answer);
                if (scanf_answer == 'Y' || scanf_answer == 'y')
                {
                    writefp = fopen(argv[2], "a+");
                    fprintf(writefp, "%s\n", line);
                    fclose(writefp);
                }
                memset(line, 0, sizeof(line));
            }
            else if (c == EOF)
            {
                printf("%s\n", line);
                printf("<Did you want to write this line to [%s]?>", argv[2]);
                scanf("%c", &scanf_answer);
                if (scanf_answer == 'Y' || scanf_answer == 'y')
                {
                    writefp = fopen(argv[2], "a+");
                    fprintf(writefp, "%s\n", line);
                    fclose(writefp);
                }
                printf("End of file\n");
                break;
            }
            if (count >= count_buf)
            {
                line = realloc(line, BUFSIZE);
                count_buf += BUFSIZE;
                if (!line)
                {
                   printf("realloc buffer failed...\s");
                   return 1;
                }
                count = 0;
            }
            sprintf(line,"%c%c", line, c);
            ++count;
        }
        fclose(fp);
        return 0;
    }

此代码将打印每一行,您决定每行写入output.txt,在文件末尾,它将打印End of file

答案 2 :(得分:0)

  

$ ./myprogram < input.txt > output.txt

您发布的命令使用名为IO重定向的shell功能从一个文件生成stdin上的输入,并将输出重定向到另一个文件的stdout。

如果您可以使用POSIX getline(),即使对于任意长度的行,也可以将行作为输入到您的程序中。有关详细信息,请参阅联机帮助页(链接如下)。

以下是一个例子:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // this is the buffer data is read to (including trailing newline)
    char *buffer = 0;
    // this will be set to the size of the buffer
    size_t buffer_size = 0;
    // this will be set to the number of bytes read
    ssize_t bytes_read;
    while ((bytes_read = getline(&buffer, &buffer_size, stdin)) != -1) {
        // do something with line
        printf("%s", buffer);
        // the same buffer will be reused in the next loop iteration
    }
    // free buffer eventually
    free(buffer);
    return 0;
}

可能的输出:

$ gcc test.c && ./a.out < test.c
#include <stdio.h>
#include <stdlib.h>

int main() {
[...]

请注意,scanf()用于获取格式化输入,而读取行则不是。我建议你在这里了解更多关于IO(在流上)的不同方法:

供参考: