Problem with a array of strings

i'm facing a problem when running this code . it skips the name input part . i don't know why . i searched everywhere and i couldn't fix it .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 #include <iostream>
#include<string>

using namespace std;

int main()
{
    int nm, Size;
    string name;

    cout <<"Enter the students total number : " <<endl;
    cin >> Size;

    cout << "Enter the students number :" << endl;
    cin >> nm ;

    string names[Size] ;

    cout << "Enter the student's full name : " << endl;
    getline(cin, name);

    names[nm] = name ;

    cout << "Student " <<names[nm]<< " "<<nm<<" is fully registered" << endl;



}
You probably need to use cin.ignore(...); and cin.clear before the getline bit.

e.g.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include<string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main()
{
    int nm, Size;
    string name;

    cout <<"Enter the students total number : " << endl;
    cin >> Size;

    cout << "Enter the students number :" << endl;
    cin >> nm ;

    string names[Size] ;

    cout << "Enter the student's full name : " << endl;
    cin.clear();
    cin.ignore(1000,'\n');
    getline(cin, name);

    names[nm] = name ;

    cout << "Student " << names[nm] << " "<<nm<< " is fully registered" << endl;

return 0;
}

I'm still something of a C++ newbie, so if there's a better or more correct way I hope someone will elaborate, but this seems to work as expected. Using getline(), your problem arises because of the new-line character from the previous input. So, you want to ignore that new-line character (this is what cin.ignore(...) does).

I think if you're being super-correct then (from other sources I've read) the cin.ignore line would be

cin.ignore(numeric_limits<streamsize>::max(),'\n');

but that would also mean adding

1
2
3
#include<limits>
using std::numeric_limits;
using std::streamsize;

at the top of the program.

There must probably be other previous forum posts on here with better explanations than I've given, so you'd be wise to check those out too, but the following easy-to-understand page may help explain cin.ignore() for you:

https://mathbits.com/MathBits/CompSci/APstrings/APgetline.htm

cin.clear() clears any error flags which may have been set on prior std::cin fails, and thus you can then merrily carry on with your getline() input.
Last edited on
Hello op10 and Cheddar99,

I will give this a try and hope I do not make any mistakes.

A line like: cin >> nm; is known as formatted input. This works best when the variable is defined as a numerical variable. The way this works is that the "std::cin" will read up to the first white space or new line (\n) whichever comes first. In the case of the "\n" it will leave this in the input buffer and move on to the next line of code. When the next cin >> someVariable; comes along having the new line in the input buffer is not a problem.

Your other option for input is, as you used, getline(cin, name);. The way this works is because you are reading what you type on the keyboard it will take everything, meaning spaces between words, and even the "\n" will be extracted from the input buffer, but is discarded and not used. Unlike the "std::cin" the "std::getline" will leave the input buffer empty.

The problem you run into is:
1
2
3
cin >> nm;
// <--- Followed by.
getline(cin, name);

The first statement will leave a "\n" in the input buffer and the second statement will take the "\n" from the input buffer and figure it is finished and move on to the next line.

In a case like this I try to follow the last "std::cin" with, as Cheddar99 suggested, with std::cin.ignore(numeric_limits<streamsize>::max(),'\n');. The use of std::cin.clear(); is not always necessary unless something caused the stream to fail. You just need to clear the input buffer. Having the std::cin.clear(); in the code does not hurt anything. It just may not be needed.

Earlier I said that std::cin >> nm; is formatted input that works best with numeric variables. I do not believe that "std::cin >>" actually can tell the difference between a short, int, long, float or double just that it is a numeric entry that is expected. So when you try to enter "a" into the variable "nm" it will cause the "cin" stream to fail. To check for this I most often use:
1
2
3
4
5
6
7
8
9
10
11
12
13
cout << "Enter the students number :" << endl;
cin >> nm ;

while (!std::cin)
{
    std::cout >> "\n Invalid entry. Try again.\n" << std::endl;

    std::cin.clear();  // <-- to reset the state bits.
    std::cin.ignore(numeric_limits<streamsize>::max(),'\n');  // <--- To clear the input  buffer.

    std::cout << " Enter the students number : ";
    std::cin >> nm;
}

This way if anything other than a number is entered for "nm" it will stay in the while loop until a good number is entered. Otherwise you leave "std::cin" in a failed state and nothing else can be entered. This is one way of using the formatted input.

You can change the output on line 6 to whatever you need.

@Cheddar99,

Your use of the "using" statements is better than OP's choice, but since this is a small program I would put the "using" line inside main and keep the scope local because it is the only place that you use them. It is best if you can avoid putting anything other than classes, prototypes and structs in the global scope.

Hope that helps,

Andy
Thanks @Cheddar99 and @Handy andy , that was very helpfull
@Handy Andy. Thanks very much for the additional and more detailed explanation. I learned a few things with that!

@op10. You're welcome. Good luck.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <vector>            // <==== see below
using namespace std;

int main()
{
    int nm, Size;
    string blank;

    cout <<"Enter the total number of students: " <<endl;
    cin >> Size;

    cout << "Enter a student's number:" << endl;
    cin >> nm ;    
    getline( cin, blank );           // <====== dummy call to clear the line feed

//  string names[Size] ;             // <====== this is illegal in standard C++ (array size not a compile-time constant)
    vector<string> names( Size );    // <====== for flexible array sizing

    cout << "Enter the student's full name: " << endl;
    getline(cin, names[nm] );        // <====== combine lines

    cout << "Student " << names[nm] << " " << nm <<" is fully registered" << endl;    // remember that array index starts at 0 ...
}


Enter the total number of students: 
10
Enter a student's number:
2
Enter the student's full name: 
lastchance
Student lastchance 2 is fully registered
Topic archived. No new replies allowed.