【问题标题】:Why is my array accepting only 2 values when I declared it as 3?为什么我的数组在声明为 3 时只接受 2 个值?
【发布时间】:2020-04-16 05:31:12
【问题描述】:

这是我的代码:

    int amount;
    cout<<"How many books are you donating? ";
    cin>>amount;
    string donation[amount];

    cout<<"Enter the titles:"<<endl;
    for (int i=0; i<amount; i+=1)
    {
        getline(cin.ignore(numeric_limits<streamsize>::max(), '\n'), donation[i]);
    }

    cout<<endl<<"You donated these:";
    for (int j=0; j<amount; j+=1)
    {
        cout<<donation[j]<<endl;
    }

即使我只为amount 输入了 3,它也接受 5 个值。然后它只打印值 1、3 和 5。

如果我直接写成getline(cin.ignore(), donation[i]);或者getline(cin.ignore(1, '\n'), donation[i]);,那么输出就变成了这样:

How many books are you donating? 3
Enter the titles:
book1
book2
book3

You donated these:
book1
ook2
ook3

我应该在cin.ignore() 中写什么以使其仅忽略\n 值?

【问题讨论】:

  • string donation[amount]; -- 这不是有效的 C++。 C++ 中的数组的大小必须由常量表达式表示,而不是运行时值。 C++ 中的动态数组是通过使用std::vector&lt;std::string&gt; donation(amount); 来完成的,这种方式不仅使程序有效 C++,而且您还可以通过使用at() 来检查数组边界,就像在getline(cin, donation.at(i)); 中一样。如果你这样做了,你会看到一个异常抛出。
  • 问题已经指出。但至于为什么你的理论上不正确的版本似乎有效,它归结为一种叫做未定义行为的阴险。索引数组越界将导致它,写入和读取越界内存也是如此。只是需要注意和避免的事情,因为它可能会导致难以在大型程序中找到错误,尤其是当原因似乎与错误无关时。
  • @Mat 我用我尝试过的方法 (cin.ignore()) 编辑了这个问题,但它仍然没有像我希望的那样工作。
  • 不要将格式化 I/O(如 cin &gt;&gt; amount)与面向行的输入(getline(cin, ....))混合。不同的方法以不同的方式处理换行符(并且以不同的方式处理错误),因此可以像您描述的那样给出奇怪的交互(例如丢失的输入)。相反,使用getline()cin 读取所有内容。由于getline() 读取一个字符串,您可以解析该字符串以从中提取(例如)amount 的值。此外,string donation[amount]amount 不是编译时常量的 C++ 无效(尽管不幸的是,一些编译器支持它作为非标准扩展)

标签: c++ arrays for-loop


【解决方案1】:

第一次cin>>读取量后需要丢弃\n,

注意:您可以使用 i++ 或 ++i 代替 i+=1(这是一种更标准的方式)

#include <iostream>
#include <string>
#include <limits>

using namespace std;

int main()
{
    int amount;
    cout<<"How many books are you donating? ";
    cin>>amount;
    string donation[amount];
    cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n'); 

    cout<<"Enter the titles:"<<endl;
    for (int i=0; i<amount; i++)
    {
        cout<< "Enter title "<<i << ":";
        getline(cin, donation[i]);
    }

    cout<<endl<<"You donated these:"<<endl;
    for (int j=0; j<amount; j++)
    {
        cout<<donation[j]<<endl;
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    数组大小必须是一个固定的编译时间常数。正如 Paul 所指出的,在运行时通过您输入到 amount 的值动态确定其大小不是有效的 C++。

    改用std::vectorstd::string 类型进行捐赠:

    #include <iostream>
    #include <vector>
    int main() 
    {
        int amount;
        std::cout<< "How many books are you donating? ";
        std::cin>> amount;
        std::vector<std::string> donation;
        std::string title;
        std::cout<< "Enter the titles: \n";
        for (int i=0; i<amount; i+=1)
        {
            std::cin>> title;
            donation.push_back(title);
        }
        std::cout<< "You donated these: \n";
        for(auto x:donation)
           std::cout<< x << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多