Bjarne Stroustrup Book - Vector 和 For 循环 - 不起作用

Posted

技术标签:

【中文标题】Bjarne Stroustrup Book - Vector 和 For 循环 - 不起作用【英文标题】:Bjarne Stroustrup Book - Vector and For loop - won't work 【发布时间】:2017-05-20 22:27:20 【问题描述】:

我在使用“C++ 编程原理和实践”中学习的一段特定代码时遇到了困难。

我无法从引用向量的循环中获得输出。我正在使用 std_lib_facilities 和 stdafx,因为这本书和 MVS 告诉我。

#include "stdafx.h"
#include "../../std_lib_facilities.h"


int main()

    vector<string>words;
    for(string temp; cin>>temp; )
        words.push_back(temp);
    cout << "Number of words: " << words.size() << '\n';

这不会产生任何结果。我会得到提示,输入一些单词,然后输入,然后什么都没有。

尝试了一些我在这里以及从其他网站获得的变体,例如:

//here i tried the libraries the guy used in his code
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()

    cout << "Please enter a series of words followed by End-of-File: ";
    vector<string> words;
    string word;
    string disliked = "Broccoli";

    while (cin >> word)
        words.push_back(word);

    cout << "\nNumber of words: " << words.size() << endl;

      // cycle through all strings in vector
    for (int i = 0; i < words.size(); ++i)
    
      if (words[i] != disliked)
          cout << words[i] << endl;
      else
          cout << "BLEEP!\n";
    
    return 0;

还是什么都没有。

在尝试了一些事情之后,通过消除,我很确定问题出在循环到向量的通信上,因为所有这些都可以正常工作:

int main()

    vector<string>words =  "hi" ;
    words.push_back("hello");
    cout << words[1] << "\n"; // this will print hello

    for (int i = 0; i < words.size();++i) 
         cout << words[i] << "\n"; // this will print out all elements 
                                   // inside vector words, ( hi, hello)
         

    cout << words.size();// this will print out number 2

    for (string temp; cin >> temp;) 
         words.push_back(temp);
        

    cout << words.size();// this won't do anything after i type in some 
                         // words; shouldn't it increase the size of the 
                         // vector?

这也不会:

int main()

    vector<string>words =  "hi" ;
    for (string temp; cin >> temp;) 
        words.push_back(temp);
        
    cout << words.size();

请问我错过了什么?提前谢谢你。

【问题讨论】:

您的代码工作正常。 wandbox.org/permlink/GYEiNuoMGABLZJpD 尝试使用 std::cout &lt;&lt; std::endl 而不是 "\n" 来刷新标准输出。 对不起,我是新手。我应该把它放在代码的什么地方? 您需要发出文件结束信号才能退出for 循环。在 Windows 的行首输入 ^Z 然后输入。在 Linux 上键入 ^D。或者使用文件并重定向输入,EOF 将在文件的实际末尾触发。 我尝试了 ^Z 输入,但仍然没有。我不知道如何进行重定向。我正在使用这本书来学习 C++。对不起。但是感谢您的帮助。 ^Z 我的意思是Ctrl-Z,以防不明白。 【参考方案1】:

输入字符串,完成后按 Ctrl+Z(后跟 Enter)(如果在 Windows 上)或 Ctrl+D 如果在 Linux 上。当您这样做时,for 循环中的cin&gt;&gt;temp; 条件将评估为 false,您的程序将退出循环。

【讨论】:

是的,我做到了。但是什么也没发生。它只写^Z。从字面上按 Ctrl 然后 Z 在我输入的最后一个字符串之后注销 ^Z。也许它与笔记本键盘有关?我在 Windows 7 上,使用 Microsoft Visual Studio 2017。 对此进行扩展:cin&gt;&gt;temp 返回 cin 本身。反过来,cin 在出现错误或已到达输入结尾时计算为 false。因此,除非您重定向程序的输入,否则它会从您的键盘读取,它没有尽头(您总是可以键入更多内容),并且永远不会返回 false。为了人为地标记输入的结束,您的提示/终端程序通常有一个特殊的序列,例如 Ctrl-D 或 Ctrl-Z,它通过关闭当前正在运行的程序的“键盘文件”来识别、抑制和操作。跨度> @JohnnyJohnny:确保在新行上键入 Ctrl-Z。 我认为您需要在 ^Z 之后(和之前)按 Enter。直到你按下最后的回车,你仍然可以撤消 ^Z 这就是为什么我的评论说:“在行首输入 ^Z 然后输入”。我承认这是一个容易忽略的细节。【参考方案2】:

首先,不必使用std_lib_facilities.h。这只是本书中使用的东西,以避免书中的每个示例都定期包含一组标准头文件,或者纠正编译器之间的非标准行为。它也是 using namespace std 的标头 - 您会发现许多示例(在 SO 和更广泛的互联网上)解释为什么在标头文件中包含 using namespace std 是非常糟糕的做法。

其次,也不必使用stdafx.h。这是由 Microsoft IDE 生成的,它提供了一种在大型项目中加速编译的方法,因为它会导致编译器使用预编译的头文件。如果您只希望使用 Microsoft 编译器,那么请随时准备好并使用这个。但是,它不是标准的 C++,可能(取决于 IDE 和项目设置)包含不适用于非 Microsoft 编译器的特定于 Windows 的标头,并且在论坛中可能会阻止使用其他编译器的人帮助您 - 因为他们会有假设您的代码使用 Microsoft 特定的扩展是一个很好的理由,这意味着它们可能无法帮助您。

第一个示例代码可以用标准 C++(不使用上面的任何一个标头)重写为

 #include <vector>    // for std::vector
 #include <string>    // for std::string
 #include <iostream>   // std::cout and other I/O facilities

 int main()
 
      std::vector<std::string> words;
      for(std::string temp; std::cin >> temp; )
           words.push_back(temp);
      std::cout << "Number of words: " << words.size() << '\n';
 

在您兴奋之前,这将显示相​​同的问题(显然没有完成)。原因实际上是循环的终止条件 - std::cin &gt;&gt; temp 只会在文件结束或流中遇到其他错误时终止循环。

所以,如果你输入

  The cow jumped over the moon

std::cin 将继续等待输入。通常需要 USER 触发和结束文件条件。在 windows 下,这要求用户在空行中输入CTRL-Z,然后按回车键。

另一种方法是使用一些预先同意的文本来导致循环退出,例如

 #include <vector>    // for std::vector
 #include <string>    // for std::string
 #include <iostream>   // std::cout and other I/O facilities

 int main()
 
      std::vector<std::string> words;
      for(std::string temp; std::cin >> temp && temp != "zzz"; )
           words.push_back(temp);
      std::cout << "Number of words: " << words.size() << '\n';
 

当输入包含单词zzz时,这将导致程序退出。例如

 The cow jumped over the moon  zzz

还有其他技术,例如一次读取一个字符,并在用户输入两个连续的换行符时停止。这需要您的代码解释每个字符,并确定单词的构成。我会把它留作练习。

请注意,标准 C++ 中无法直接读取击键 - 上述问题与标准流的工作方式以及与主机系统的交互方式有关。

用户还可以通过将相同的文本放入实际文件中“按原样”使用程序,并且(当程序运行时)将程序的输入重定向到来自该文件。例如your_executable &lt; filename

【讨论】:

谢谢。但为什么它在这里工作? wandbox.org/permlink/GYEiNuoMGABLZJpD 。我的意思是,没有任何迹象表明特定的行为。至少,我什么都看不见。 当使用这样的远程站点时,浏览器会将输入提供给服务器。服务器可能正在执行我描述的重定向。 “因为他们有充分的理由假设您的代码使用了 Microsoft 特定的扩展,这意味着他们可能无法帮助您。” 无知的人发布的典型 FUD .这可能是一个优势,因为它阻止了无益的人试图帮助你。当然,使用预编译的头文件并不是必要的,但这并不会造成错误。许多其他编译器都有类似的功能。仅仅因为你不熟悉它的工作原理并不意味着它没有用。像这样的题外话对我无法投票的问题提供了有用的答案。 @CodyGray - 坦率地说,无论你是否赞成这个答案,我都不会打扰。如果问题包含特定于他们不使用的编译器的功能,人们更有可能跳过一个问题,因为他们不太可能提供帮助。因此,如果一个人想最大限度地获得有关标准 C++ 的问题的有用帮助(如本例中),最好删除编译器特定的功能,除非问题是专门关于这些功能的 - 这不是这种情况问题。 这个答案的“主题”部分实际上比公认的答案有用得多,因为它解释了发生了什么以及为什么以及如何修复/解决它。

以上是关于Bjarne Stroustrup Book - Vector 和 For 循环 - 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

C++之父Bjarne Stroustrup:程序员在数学上付出的努力,永远也不会白费

无法编译应该从 Bjarne stroustrup 的编程原理和实践的第 12 章工作的图形代码

由于在 Bjarne Stroustrup“使用 c++ 的编程和实践”中找不到符号而导致的链接错误

C++之父Bjarne Stroustrup:程序员在数学上付出的努力,永远也不会白费

代码在 Visual c++ 中无法按预期工作(来自 bjarne stroustrup 编程和原则书 2n 版的示例)

模板 :: Stroustrup 的示例未编译