为什么当我输入 stop 时我的 while 循环没有停止?

时间:2021-06-12 03:39:28

标签: c++

我在 C++ 中有一个 while 循环

bool stopped = false;
while (!stopped) {
  string input;
  cin >> input;
  if (input == "stop") {
    stopped = true;
  }
}

当我使用 stop 时,它不会停在只有一个空行的地方

我的完整代码是

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
  bool stopped = false;
  ofstream script;
  string scriptname;
  getline(cin >> ws, scriptname);
  script.open(scriptname);
  while (!stopped) {
    string input;
    cin >> input;
    if (input == "line") {
      string lineInput;
      getline(cin >> ws, lineInput);
      int i = lineInput.find(',');
      lineInput[i] = ':';
      script << lineInput << endl;
    } else if(input == "wait") {
      string waitInput;
      getline(cin >> ws, waitInput);
      if (!(waitInput.find(',') != string::npos)) {
        script << "***" << endl;
      } else {
        script << "***" << waitInput << endl;
      }
    } else if(input == "action") {
      string actionInput;
      getline(cin >> ws, actionInput);
      int i = actionInput.find(',');
      actionInput += ')';
      actionInput.insert((i + 2), 1, '(');
      script << actionInput << endl;
    } else if(input == "stop") {
      stopped = true;
    }
  }
  script.close();
  return 0;
}

我正在使用输入,我首先输入“test”然后按回车,然后我输入“stop”并按回车,它生成文件,但在我使用停止部分后,它只有一个空行。< /p>

事实证明,这只是因为我用来运行它的 atom 包由于某种原因并没有停止它,我尝试使用 konsole 而不仅仅是 atom 并且它起作用了

1 个答案:

答案 0 :(得分:2)

好吧,由于此代码在我输入 stop 时停止(我建议在本地尝试以确认),因此您尚未向我们展示的代码中肯定有问题.

#include <iostream>
#include <string>

int main() {
    bool stopped = false;
    while (!stopped) {
        std::string input;
        std::cin >> input;
        if (input == "stop") {
            stopped = true;
        }
        // some more code here?
    }
}

我猜循环正在停止,但是您拥有的其他代码仍在对您在评论中提到的输出文件执行某些操作。例如,如果您在我的 // some more code here? 注释所在的位置有一些代码,即使您输入了 stop,它也会执行。实际循环在返回到 while 位之前不会退出。

在我们看到真正的代码之前,我们无能为力。


而且,既然您已经添加了完整的代码,我非常确信问题不在于代码。在我的系统上运行该确切代码给出:

pax:~> g++ --std=c++17 -Wall -Wextra -Wpedantic -o prog prog.cpp && ./prog
test
stop
pax:~> wc test
0 0 0 test

它在 stop 退出,结果文件不包含任何内容,正如预期的那样。

现在它可能是由您运行它的方式引起的环境问题。我知道在 Visual Studio 中运行东西有时会让窗口为你打开,但它至少会打印一些东西来通知你:

C:\Users\Pax\ConsoleApp1.exe (process 5400) exited with code 0.      Press any key to close this window . . .

如果您从 IDE 运行它,我会从适当的 shell(cmd.exe 或终端)运行它,只是为了检查是否是这种情况。


顺便说一句,我对您的代码进行了一些修改,以便您了解它在每个点的作用(带有提示,而不仅仅是带有光标的空行):

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    bool stopped = false;
    ofstream script;
    string scriptname;
    cout << "scriptname: ";
    getline(cin >> ws, scriptname);
    script.open(scriptname);
    while (!stopped) {
        string input;
        cout << "input: ";
        cin >> input;
        if (input == "line") {
            string lineInput;
            cout << "lineInput: ";
            getline(cin >> ws, lineInput);
            int i = lineInput.find(',');
            lineInput[i] = ':';
            script << lineInput << endl;
        } else if(input == "wait") {
            string waitInput;
            cout << "waitInput: ";
            getline(cin >> ws, waitInput);
            if (!(waitInput.find(',') != string::npos)) {
                script << "***" << endl;
            } else {
                script << "***" << waitInput << endl;
            }
        } else if(input == "action") {
            string actionInput;
            cout << "actionInput: ";
            getline(cin >> ws, actionInput);
            int i = actionInput.find(',');
            actionInput += ')';
            actionInput.insert((i + 2), 1, '(');
            script << actionInput << endl;
        } else if(input == "stop") {
            stopped = true;
        }
    }
    script.close();
    cout << "EXIT\n";
    return 0;
}

对于写入文件的所有内容,这似乎工作得很好。但是, 至少有一个小的编码错误(多步):

int i = lineInput.find(',');
lineInput[i] = ':';

如果您输入一行不带逗号,i 将设置为 std::npos,即 -1(或未签名的等效项)。如果您随后在上面的第二行中使用它作为索引,它会更改字符串末尾的 字符或字符串开头之前的字符。这两种情况都是未定义的行为(这就是我没有花太多时间研究它的原因)。

您可能应该拥有类似于 wait 案例中的情况的保护:

int i = lineInput.find(',');
if (i != std::npos) {
    lineInput[i] = ':';
}

action 的情况下,您还需要类似的东西(对于 insert 调用),我会去掉 wait 中的双重否定:< /p>

// if (!(waitInput.find(',') != string::npos)) {
// Instead, you <humour> shouldn't not </humour> do it this way:
if (waitInput.find(',') == string::npos) {
    script << "***" << endl;
} else {
    script << "***" << waitInput << endl;
}