Hi guys,

Looking at this I know it is straightforward, but that hasn't meant that I have been able to get the solution - so here I am! I am entering serial numbers into a set container which is of type string. I want to be able to enter serial numbers into the set until the user simply presses enter, meaning that "blank" stops input. For the code that I will show you, I have used "X" as the way the user stops input. Here is the code:

ItemizedProductLine::ItemizedProductLine(ProductCode pc, double rrp, double sp, int oh, char* desc): ProductLine(pc, rrp, sp, oh, desc){
    
    string serial = "0";

    while(serial.at(0) != 'X')
    {
        cout << "Please enter serial number:" << endl;
    
        cin >> serial;
        
        serialNumbers.insert(serial);
    }
}

As you can see, this does allow the user to stop entering data by pressing "X". However, I can see that this is a horrible way of doing it. Furthermore, it does not achieve my real goal of having the user simply press enter to stop input.

I should add that I am aware that using an array would make it very easy. However, I am limited by the fact that I am entering serial numbers as strings. Furthermore, I now really want to know how you do this using strings! Can anyone shed any light on this problem? Thanks in advance.

Daniel

Dani AI

Generated

Both , and are right: prefer std::getline over operator>> when an empty line should stop input (and when serials may contain spaces). A blank line is a much clearer sentinel than a special character like 'X', which could legitimately appear in a serial. The loop below shows a robust pattern that also handles EOF, strips stray CR from Windows-style input, ignores lines made only of whitespace, and reports duplicates using the set insertion result.

#include <iostream>
#include <string>
#include <set>
#include <algorithm>

void readSerials(std::set<std::string>& serialNumbers)
{
    std::string s;
    while (true)
    {
        std::cout << "Please enter serial (empty line to finish): ";
        if (!std::getline(std::cin, s)) break; // EOF or error
        if (!s.empty() && s.back() == '\r') s.pop_back(); // handle CRLF sources
        auto first = s.find_first_not_of(" \t");
        if (first == std::string::npos) break; // blank or whitespace-only -> stop
        auto last = s.find_last_not_of(" \t");
        s = s.substr(first, last - first + 1); // trim
        auto result = serialNumbers.insert(s);
        if (!result.second) std::cout << "Duplicate ignored\n";
    }
}

When mixing formatted input and line-based input, a leftover newline can make the first getline return immediately. That is resolved by consuming the rest of the line first (for example std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');) or by using std::getline(std::cin >> std::ws, s) to skip leading whitespace. Decide whether leading/trailing spaces are meaningful for serials; if not, normalize (trim, maybe uppercase with std::transform) before inserting. The std::set already prevents duplicates; checking the insert return value allows reporting or handling of repeats.

Recommended Answers

All 4 Replies

using getline should work for you. I would suggest this

// inside function
string serial;
cout << "Please enter a serial number. Enter to quit: ";
getline(cin, serial);
while(!serial.empty())
{
    serialNumbers.insert(serial);
    cout << "Please enter a serial number. Enter to quit: ";
    getline(cin, serial);
}

It is to be noted there is no error checking here so the user could enter a letter and it would be excepted.

use getline() instead of >> operator and it will work

int main()
{

    string serial = "0";

    while(serial != "")
    {
        cout << "Please enter serial number:" << endl;
    
        getline(cin,serial);
        
    }
    cout << "All done\n";
}

[edit]Oops! didn't see Nathan's reply [/edit]

In this case, using getline is appropriate:

ItemizedProductLine::ItemizedProductLine(ProductCode pc, double rrp, double sp, int oh, char* desc): ProductLine(pc, rrp, sp, oh, desc)
{
  for (;;)
  {
    cout << "Please enter serial number:" << endl;
    string serial;
    getline(cin,serial);
    if (serial.empty())break;
    serialNumbers.insert(serial);
  }
}

Thanks guys! Much appreciated. This site really is fantastic! Have a great day/night!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.