【问题标题】:[c++]checking for end of file[c++]检查文件结尾
【发布时间】:2016-02-15 00:14:29
【问题描述】:

我已经用 C++ 构建了一个简单的 Linux shell。它可以接收标准 bash 命令、重定向到文件等。但是,我想要的是它能够接收输入,例如,如果我有一个包含

的 commands.txt 文件
ls -l /
some_invalid_command
echo this displays stuff

然后我将它通过管道传输到我的 a.out 中

$./a.out < commands.txt

我希望它运行里面的命令,就好像我输入了它们一样。但是,当我这样做时,我遇到了一个无限循环,其中'$'提示会反复显示,直到我按下 ctrl+c。我很确定原因是我没有在代码中的任何位置检查文件结尾。

所以我的问题是,在这种情况下我将如何检查文件结尾?我认为角色是“^d”,但我不确定如何检查。像这样的东西有用吗?

if (inputString == "\^d") {
    exit = true;
}

我只担心在文件运行后我想在 shell 中输入更多信息。将 exit 设置为 true 会告诉 shell 关闭。

编辑:请求的代码...

void Shell::getInput() {
        emptyQueue();
        cout << "$ ";
        getline(cin, inputString);
        fillQueue();
};

void Shell::fillQueue() {

        if (inputString.empty()) {
                return;
        };

        int i = inputString.find_first_not_of(" ");
        int j = inputString.find_last_not_of(" \r\n");
        int k;
        string stringToAdd;

        while (i != -1) {
                k = i;
                while (inputString.at(k) != ' ') {
                        if (k == j) {
                                break;
                        };
                        k++;
                };

                if (k != j) {
                        k--;
                };

                stringToAdd = inputString.substr(i, k - i + 1);
                i = inputString.find_first_not_of(" ", k + 1);

                commandQueue.push_back(stringToAdd);
        };

        i = 0;
        while (i < commandQueue.size()) {
                pointers[i] = commandQueue[i].c_str();
                i++;
        };
};

【问题讨论】:

  • 你能说明你是如何从命令文件中读取的吗?
  • 我认为您的错误在于假设 inputString 实际上已成功读取(我假设使用 std::getline),您实际上需要检查流中是否存在错误并在发生错误时终止(流关闭) .您检查 Ctrl-D。
  • 如果有帮助,我进行了编辑。
  • 也许您的字符串修剪功能在某处失败,因为输入文件中的行结尾不同?你可以试试这些:stackoverflow.com/questions/216823/…
  • 不是这样,我在这里找到了我想要的答案:stackoverflow.com/questions/1428911/detecting-eof-in-c

标签: c++ linux bash shell


【解决方案1】:

文件结尾不是字符本身。

当您到达文件末尾时,任何读取更多字符的尝试都会返回并指示已读取 0 个字符。

您没有显示有问题的代码,但您必须运行从标准输入读取下一行文本的循环。通常,您可以明确检查读取的字符数是否为 0,或者如果您使用的是 std::istream,则使用 eof() 方法。

【讨论】:

  • 我没有使用 istream,而且我很确定我也不允许这样做。我将在对 OP 的编辑中包含读取输入的代码和其中调用的方法之一。
  • @ZachThompson:“我没有使用 istream” - 你的代码包含 getline(cin, inputString); - cin istream
  • @TonyD 哦,对不起。
【解决方案2】:

如果文件以(默认)文本模式打开,Ctrl+D 被翻译为文件结尾。所以你只需要确保你的循环直到没有输入,通常是:

while ( getline(cin, inputString) ) {  // or while (cin>>inputString)
    ...
}

【讨论】:

    【解决方案3】:
    void Shell::getInput() {
        emptyQueue();
        cout << "$ ";
        getline(cin, inputString);
        if(feof(stdin)) {
            exit = true;
            return;
        };
        fillQueue();
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2015-03-22
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      相关资源
      最近更新 更多