【问题标题】:Need help implementing kittycat function in C using a function需要帮助在 C 中使用函数实现 kittycat 函数
【发布时间】:2021-11-04 16:45:28
【问题描述】:

需要帮助获取 display_stream 函数以从 Shell 中的标准输入读取。当我在 Shell 中键入“./kittycat”时,当它应该从标准输入读取时,我变得空白。其他一切都适用于一个或多个参数,它读取文本文件(./kittycat test.txt test2.txt),如果我输入'./kittycat error.txt',它会说找不到错误文件。我只是缺少一种使用函数 display_stream 从标准输入读取的方法。包括 shell 输出与预期的屏幕截图。

    [enter image description here][1]#include <stdio.h>
    #include <stdlib.h>
    
    void display_stream(FILE *fptr);
    
    int
    main(int argc, char *argv[])
    {
        int i;
    
        // if no args given, read from stdin (just like shell/cat)
        if (argc < 2)
            display_stream(stdin);
    
        for (i = 1; i < argc; i++) {
            FILE *fptr = fopen(argv[i], "r");
    
            if (fptr == 0) {
                printf("error: file not found.");
                continue;
            }
    
            display_stream(fptr);
            fclose(fptr);
        }
    
        return 0;
    }
    
    void
    display_stream(FILE *fptr)
    {
    
        int x;
    
        /* read one character at a time from file, stopping at EOF,
            which indicates the end of the file. */
        while ((x = fgetc(fptr)) != EOF)
            putchar(x);
    }

MY output What is expected

【问题讨论】:

  • 我觉得没问题。你有什么问题?
  • 显示标准输入和文件中的文本 你应该向用户询问一些文本吗?那部分不清楚。
  • 你需要在display_stream(fptr)之后调用fclose(fptr)
  • "r\n" ?? open-mode argument 中的换行符在做什么?
  • 试试fopen( argv[i], "r\n" ) --> fopen( argv[i], "r" )

标签: c file-io


【解决方案1】:
  1. fclose 移出display_stream,它不属于那里。将其放在致电display_stream 之后。
  2. 在循环之前或之后添加display_stream(stdin)main(这次没有fclosestdin 不应关闭)。它应该可以正常工作。

它可能会逐行从标准输入复制,但这是由于程序外部的缓冲导致禁用 AFAIK 并不容易。

另外,printf( "%c", x ) 可以是 putchar(x)

【讨论】:

  • 我做了你的改变,但是无论我把 display_stream(stdin) 放在循环之前还是之后,它什么都不做,当我在 Shell 中执行 './kittycat' 或任何命令时它没有给出我的 '~/Assignment-1$' 不再是空白,当我按下时输入更多的空白。我必须刷新或按 control-C 才能在 Shell 中键入命令
  • 嗯...你明白“stdin”是什么意思吗?
  • 不是 100%,但我只是想匹配预期的输出,应该是几行文本或标准代码,而不仅仅是空白
  • 即“标准输入”。也就是键盘,除非你使用重定向。尝试在程序运行时输入一些内容;按下 后,它将重复您键入的行。
  • 正如 Craig Estey 所提到的,重定向就像 ./kittycat &lt; foo.txt 一样完成。当运行这样的程序时,它的标准输入是foo.txt而不是键盘。
【解决方案2】:

检查argc 以决定程序是应该从stdin 读取还是应该打开argv[i] 来打开文件。


这是重构的[和注释]代码:

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

void display_stream(FILE *fptr);

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

    // if no args given, read from stdin (just like shell/cat)
    if (argc < 2)
        display_stream(stdin);

    for (i = 1; i < argc; i++) {
        FILE *fptr = fopen(argv[i], "r");

        if (fptr == 0) {
            printf("error: file not found.");
        }
        else {
            display_stream(fptr);
#if 1
            fclose(fptr);
#endif
        }
    }

    return 0;
}

void
display_stream(FILE *fptr)
{

    int x;

    /* read one character at a time from file, stopping at EOF,
        which indicates the end of the file. */
    while ((x = fgetc(fptr)) != EOF) {
        printf("%c", x);
    }

    // don't close this here -- let caller do it (e.g. stdin should _not_ be
    // closed and only caller knows whether the stream is stdin or not)
#if 0
    fclose(fptr);
#endif
}

这是一个稍微更干净的版本:

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

void display_stream(FILE *fptr);

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

    // if no args given, read from stdin (just like shell/cat)
    if (argc < 2)
        display_stream(stdin);

    for (i = 1; i < argc; i++) {
        FILE *fptr = fopen(argv[i], "r");

        if (fptr == 0) {
            printf("error: file not found.");
            continue;
        }

        display_stream(fptr);
        fclose(fptr);
    }

    return 0;
}

void
display_stream(FILE *fptr)
{

    int x;

    /* read one character at a time from file, stopping at EOF,
        which indicates the end of the file. */
    while ((x = fgetc(fptr)) != EOF)
        putchar(x);
}

【讨论】:

  • 首先感谢您的帮助。我尝试了上面的代码,但我仍然得到空白。我更新了上面的代码,并在我的输出中添加了图片链接,这样你就可以看到问题了
  • 我在发布之前[在两种模式下]预先测试了代码。 可能是[内核] TTY 驱动程序问题。也就是说,您必须键入 ctrl-D 才能强制执行 EOF。要查看stdin 是否有效,请尝试(例如)./kittycat &lt; foo.txt。它应该像这样工作:./kittycat foo.txt
  • @BertoRoman 尝试在display_stream() 末尾打印一个换行符。
  • 我做了 ./kittycat
  • 赋值说“ display_stream 函数应该将文件流作为参数,并重复从文件中读取一个字符并将其显示到标准输出,直到到达文件末尾。这个函数应该是用于从标准输入和文件中读取和显示文本"
猜你喜欢
  • 2018-07-17
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-24
  • 1970-01-01
  • 2018-04-10
相关资源
最近更新 更多