【问题标题】:fputs(), fgets(), ferror() questions and C++ equivalentsfputs()、fgets()、ferror() 问题和 C++ 等价物
【发布时间】:2012-01-30 04:51:38
【问题描述】:

所以我正在阅读一本关于用 C 编写 shell 的书,我想尝试用 C++ 编写它。我遇到了以下代码:

for( ; ; ) 
{
    if (fputs(PROMPT, stdout) == EOF)
        continue;

    if (fgets(inbuf, MAX, stdin) == NULL)
        continue;

    //and so on....
}
  1. 这里我不明白fputs()的用法。

    (a) 如果 stdout 是终端,EOF 有什么意义吗?除了流可能已经关闭之外,您可以向终端写入哪些类型的错误?

    (b) 如果 stdout 以前被重定向并且实际上是一个管道或文件,那么可能会出现几个不同的错误。它们在哪里列出?见下文 (c)。

    (c) 在上面的 (b) 之后, ferror() 似乎没有那么有用。它的返回值是否映射到 errno 的返回值,因此与使用 perror() 之类的返回值相同吗?为了做类似的事情而保存的常量在哪里

      if (ferror() == SYSTEM_ERROR_13)
    

    (d) 在上面的代码中,如果 fputs() 确实返回错误,为什么“继续”会起作用?是否不需要先使用 clearerr() 之类的方法清除错误,否则它会反复失败?

  2. 是C++中的等价代码:

    for( ; ; ) 
    {
        if (! cout << PROMPT)
        {
            cout.clear();
            continue;
        }
    
        if (! getline(cin, inbuf))
        {
            cin.clear();
            continue;
        }
    
        //and so on....
    }
    

【问题讨论】:

  • 在我个人看来,如果交互式 shell 丢失输入或输出流,它应该终止。没有互动就无法互动。
  • 所以它应该死了?如果您丢失 stdout/stderr 是否适合尝试写入系统日志?如果你的 shell 是由另一个程序的 system() 调用启动的,是否有适当的退出值可以传回?
  • 您可以将其视为用户请求退出并正常关闭。例如,像 Bash 一样,当您按下 Ctrl-D 时。

标签: c++ c


【解决方案1】:
if (fputs(PROMPT, stdout) == EOF)
    continue;

a) 如果 stdout 是终端,EOF 是否有任何意义? - fputs 函数在出错时返回 EOF。

b) 不同的错误似乎是可能的。它们在哪里列出? - 写入标准输出失败的原因真的很重要吗?你确定要深入吗?

c) ferror() 似乎没有帮助...使用类似 perror() 的东西? 它们都基于全局变量 errno 工作。尽管perror 对您来说是更好的选择,因为它以指定格式输出到stderr

d) 在上面的代码中,如果 fputs() 确实返回错误,为什么“继续”会起作用? - 这似乎是不正确的。

根据这些事实,它应该是这样的:

if (fputs(PROMPT, stdout) == EOF)
{
    perror("The following error occurred");
    exit(1);
}

if (fgets(inbuf, MAX, stdin) == NULL)
{
    perror("The following error occurred");
    continue;
}

2.是 C++ 中的等效代码吗? - 没有。有一个区别:fgets 读取行并且字符串中包含 '\n',而 getline 读取行但分隔符 ('\n' ) 不存储。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多