2

Here's my code:

    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;
    }

This accepts 5 values even though I only input 3 for amount. Then it prints only values 1, 3, and 5.

If I just write it as getline(cin.ignore(), donation[i]); or getline(cin.ignore(1, '\n'), donation[i]);, then the output becomes like this:

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

You donated these:
book1
ook2
ook3

What should I write in the cin.ignore() for it to ignore just the \n value?

Novelcie
  • 56
  • 7
  • 1
    https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction – Mat Apr 16 '20 at 05:33
  • 5
    `string donation[amount];` -- This is not valid C++. Arrays in C++ must have their sizes denoted by a constant expression, not a runtime value. Dynamic arrays in C++ are done by using `std::vector donation(amount);` Not only is doing things that way makes the program valid C++, you get the added ability to check your array boundaries by using `at()`, like in `getline(cin, donation.at(i));`. If you did that, you will see an exception thrown. – PaulMcKenzie Apr 16 '20 at 05:33
  • The problem was already pointed out. But as for why your theoretically incorrect version appears to work, it's down to something insidious called undefined behaviour. Indexing an array out of bounds will cause it, as will writing to and reading from that out of bounds memory. Just something to be aware of and avoid, as it can cause difficult to find bugs in larger programs, especially when the cause seems unrelated to the bug. – George Apr 16 '20 at 05:42
  • @Mat I edited the question with what I've tried (`cin.ignore()`) but it's still not working as I hoped. – Novelcie Apr 16 '20 at 05:55
  • Don't mix formatting I/O (like `cin >> amount`) with line-oriented input (`getline(cin, ....)`). The different approaches handle newlines differently (and errors differently) so can give strange interactions like you describe (e.g. lost input). Instead, use `getline()` to read EVERYTHING from `cin`. Since `getline()` reads a string, you can parse the string to extract (say) a value of `amount` from it. Also, `string donation[amount]` where the value `amount` is not a compile-time constant is not valid C++ (although, unfortunately, some compilers support it as a NON-STANDARD extension) – Peter Apr 16 '20 at 06:12

2 Answers2

1

You need to discard the \n after the first cin>>amount read,

note: instead of i+=1 it you can use either i++ or ++i (is a more standard way)

#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;
}
SeventhSon84
  • 364
  • 1
  • 4
1

Array size must be a fixed compile-time constant. Dynamically determining its size at runtime by the value you input to amount is not valid C++, as pointed out by Paul.

Use a std::vector of std::string type for donation instead:

#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";
}
Anirban166
  • 3,162
  • 4
  • 11
  • 27