When I run the following code and insert a new line (press enter) when prompted for the golf structure, the second call to the function doesn't request input and finishes as if I've pressed enter again.
I've read up on : cin.get() , cin.clear() , cin.ignore(...) but nothing seems to help.
I'm pretty sure that it has nothing to do with multiple .cpp files and the header but I'm putting the code as is.
I'm using Visual Studio C++ 2010 - Express.
Thanks in advance for your help!
header file : golf.h
#ifndef GOLF_H
#define GOLF_H
const int Len = 40;
struct golf{
char fullname[Len];
int handicap;
};
int setgolf(golf & g );
void showgolf(const golf & g );
#endif
golf.cpp
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int setgolf(golf & g ){
cout << "Enter a name for the golf structure:" << endl;
if (cin.get(g.fullname,Len)) {
cin.get(); // deals with the '\n' incase the user inputs a valid string
return 1;
}
else{
return 0;
}
}
void showgolf(const golf & g ){
cout << "this golf structure contains the following information:" << endl;
cout << "name: " << g.fullname << endl ;
cout << "handicap: " << g.handicap << endl ;
}
main ()
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
golf myGolf;
// check of int setgolf(golf & g );
int answ = setgolf(myGolf); //try to input empty string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
answ = setgolf(myGolf); // normal string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
return 0;
}
This problem happens when you just press enter in the first prompt. The input stream is marked as eof, an error condition flag (that's why it returns 0). The input stream then stops working.
It seems that you're using a kind of old C++, pre ISO 1998, while I don't think you need that. However, if you want to stick with your approach, then do the following: after cin.getline()
(no need to return anything) write: cin.clear(); cin.sync();
, as follows:
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
cin.clear();
cin.sync();
}
Now, about modernizing your code. First of all, you can use the standard library's class string
, which is able to store a string literal, even growing if needed, without giving a maximum value of chars. This is somewhat confusing, since you are including the header string
, which will include that class, but you're not using it. The use of string
also comes with other advantages, such as automatically correcting the potential buffer overflow which could happen in your Golf
structure. So I would change your structure to be:
struct Golf{
string fullname;
int handicap;
};
Now you can use getline()
, in utility
, which reads a whole line and stores it in string
, doing all the magic for you. So you could change your golf.cpp
file, to:
#include <utility>
//...
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
}
You can now also change the return type to void
. It is not probable to experience an error of any kind while using getline()
. Anyway, take into account that you could return bool
(boolean type), which is a built-in type, with literals true
and false
.
I am certain that you could change your main()
now, to a simpler style:
int main()
{
Golf myGolf;
setGolf(myGolf);
showGolf(myGolf);
setGolf(myGolf);
showGolf(myGolf);
return 0;
}
Finally, you could consider encapsulating your information in a class, instead of a struct, but that is a whole different issue.
Hope this helps.