cin.Getline returns nothing - c++

I am trying to learn c++. I am on strings now.
I have written this simple method that should ask to input a string and then return it. To do so I am using cin.getLine() method but the string is not printed after I use cin.getLine()
string getString(char string[])
{
cout << "Please enter a string to process ";
cin >> string;
cout << "String in getString before process: " << string << "\n";
cin.getline(string, STRINGSIZE);
cout << "String after processing: " << string << "\n"; // here string is not printed
return string;
}
Can anybody help me to understand what I am doing wrong? Thank you

you are first reading string to std::string with cin >> string; and then read again something from cin with cin.getline(string, STREAMSIZE);
it is not necessary, read it once and return:
string getString(char string[]){
cout << "Please enter a string to process ";
cin >> string;
cout << "String in getString before process: " << string << "\n";
// process this, do whatever you describe as processing it
cout << "String after processing: " << string << "\n"; // string is printed
return string;
}
otherwise, if you want to use getline, do:
std::string name;
std::cout << "Please, enter your full name: ";
std::getline (std::cin,name); // or std::getline(std::cin,string, 'r'); to read
//only to delimiter character 'r'
std::cout << "Hello, " << name << "!\n";
so thing to remember is use getline OR cin, not both simultaneously unless there is really some special reason

Related

C++ - How to know where to put cin.ignore

I have a code from my friend and we do not know how to use cin. ignore very well.
Our problem is that we are using do while and at the end of loop we want to ask user to enter if he wants to again enter some values as you will see from the code itself.
If the answer is 'y' then he can "write" again but the problem is we are using getline and we have the problem with the first getline in this loop. The program does not recognise it after the first time use.
Here is the code:
int main() {
ofstream datoteka("podaci.txt", ios::app);
if (datoteka.fail()) {
cout << "Ne postojeca datoteka";
exit(1);
}
string ime;
string prezime;
char pol;
int godiste;
float prosjek;
char odluka;
do{
system("CLS");
cout << "Unesite ime: ";
getline(cin, ime);
datoteka << ime;
cout << "Unesite prezime: ";
getline(cin, prezime);
datoteka << " " << prezime;
cout << "Unesite pol(M - musko, Z - zensko): ";
cin >> pol;
datoteka << " " << pol;
cout << "Unesite godiste: ";
cin >> godiste;
datoteka << " " << godiste;
cout << "Unesite prosjek: ";
cin >> prosjek;
datoteka << " " << prosjek << endl;
cout << endl;
cout << "Da li zelite unijeti podatke za jos jednu osobu?" << endl;
cout << "[Y] za da, [N] za ne : ";
cin >> odluka;
} while (odluka != 'N' || odluka !='n');
The problem is with the
getline(cin,ime);
It wont recognize it after the first time use.
Can someone help me?
The basic problem is that this code mixes two different forms of input. Stream extractors (operator>>) do formatted input; they skip whitespace, then try to interpret non-whitespace characters, and stop when they encounter something that doesn't fit with what they're looking for. That works fine when you have multiple extractors: std::cin >> x >> y >> z;,
getline() is an unformatted input function; it grabs whatever is in the input stream, up to the first newline.
If you mix them you can get into trouble. The usual way to get around this is to call some variation of cin.ignore() when you switch from formatted to unformatted input, and that's where the code in the question goes astray.
At the end of the loop, the code calls std::cin >> odluka;. That reads one character from the console, and leaves any additional input in place. Since the console itself typically will sit waiting for characters until it sees a newline character, typing that single character also requires hitting the Enter key, which puts a newline into the input stream. The extractor leaves the newline there. When the loop repeats, the code calls std::getline(std::cin, ime), which sees the newline character and stops reading input.
So whenever you transition from formatted input to unformatted input you have to clear out any remnants from the previous input efforts.
Or you can always read a line at a time, and parse the input yourself.
i'm not sure exactly what the problem is. i took your code and it does what it's supposed to be doing on my machine (made a few adjustments so i can understand what's going on):
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace::std;
int main() {
ofstream datoteka("podaci.txt", ios::app);
if (datoteka.fail()) {
cout << "Ne postojeca datoteka";
exit(1);
}
string ime;
string prezime;
char pol;
int godiste;
float prosjek;
// changed it to a char pointer
char odluka[] = { "Y" };
do{
system("CLS");
cout << "1: ";
getline(cin, ime);
datoteka << ime;
cout << "2: ";
getline(cin, prezime);
datoteka << " " << prezime;
cout << "3: ";
cin >> pol;
datoteka << " " << pol;
cout << "4: ";
cin >> godiste;
datoteka << " " << godiste;
cout << "5: ";
cin >> prosjek;
datoteka << " " << prosjek << endl;
cout << endl;
cout << "6" << endl;
cout << "[Y], [N]: ";
cin >> odluka;
// added this. it was not waiting for my input properly.
cin.get();
// print results
system("cls");
printf("results (press any key to move on)\n\n1: %s\n2: %s\n3: %c\n4: %d\n5: %.02f\n6: %c\n\n", ime.c_str(), prezime.c_str(), pol, godiste, prosjek, odluka);
getchar();
} while (_stricmp(odluka, "n")); // while "odluka" is not "n" or "N" (the _stricmp is not case-sensitive so they both return the same result)
system("cls");
printf("press any key to exit!\n");
getchar();
getchar();
}
here is the output from "podaci.txt":
test1 test1 1 1 1.1
test2 test2 2 2 2.2
consider using scanf/sprintf/printf with c strings in the future if this keeps malfunctioning perhaps?

cin.get() function in C++

I have been studying c++ and came across the code below. I dont understand why they have to use the get(c) in "cin.get(straddress, sizeof(straddress), fdelim).get(c)". The code works just fine without this get(c). Can someone enlighten me on the use of get(c)? The purpose of the program is to read data of mixed type.
const char fdelim = '\t';
char straddress[256];
int zip;
char c;
cout << "Enter a record of data: ";
cin.get(straddress, sizeof(straddress), fdelim).get(c) >> zip;
cout << "\nStreet address : " << straddress << endl;
cout << "\nZip/Postal code: " << zip << endl;
The line
cin.get(straddress, sizeof(straddress), fdelim).get(c) >> zip;
reads everything up to fdelim to straddress, then reads the delimiter to c, and then reads the zip code to zip.
It could have been written better as:
cin.get(straddress, sizeof(straddress), fdelim);
cin.get(c);
cin >> zip;
Since c is not used, it could have been ignored too.
cin.get(straddress, sizeof(straddress), fdelim);
cin.ignore(1); // Read and discard 1 character.
cin >> zip;
Assuming the user types in fewer than 255 characters before typing in a \t character, the first call to cin.get() will stop reading when the \t character is reached, but will not extract it from cin. The next call to cin.get() will then extract the \t.
I would opt to use std::istream::getline() instead, which reads the delimiter but does not store it in the caller's buffer:
const char fdelim = '\t';
char straddress[256];
int zip;
cout << "Enter a record of data: ";
cin.getline(straddress, sizeof(straddress), fdelim);
cin >> zip;
cout << "\nStreet address : " << straddress << endl;
cout << "\nZip/Postal code: " << zip << endl;
Even better, I would use std::getline() instead, which reads into a std::string instead of a char[] buffer:
const char fdelim = '\t';
string straddress;
int zip;
cout << "Enter a record of data: ";
getline(cin, straddress, fdelim);
cin >> zip;
cout << "\nStreet address : " << straddress << endl;
cout << "\nZip/Postal code: " << zip << endl;

String phrase ends at space?

I am wringing a simple code to learn more about string. When I ran my code it would not print my last name. Can someone explain why? I used string phrase to store it and it only appears to have stored my first name. Here is the code.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
cout << "Exercise 3B" << endl;
cout << "Kaitlin Stevers" << endl;
cout << "String arrays" << endl;
cout << endl;
cout << endl;
char greeting[26];
cout << "Please enter a greeting: " << endl;
cin >> greeting;
cout << "The greeting you entered was: " << greeting << endl;
string phrase;
cout << "Enter your full name " << endl;
cin >> phrase;
cout << greeting << ", how are you today " << phrase << "?" << endl;
return 0;
}
I used string phrase to store it and it only appears to have stored my first name.
That makes sense.
cin >> phrase;
will stop reading when it encounters a whitespace character in the input.
To read the full name you can use one of the following approaches.
Use two calls to cin >>.
std::string first_name;
std::string last_name;
cin >> first_name >> last_name;
Use getline to read the entire line. getline will read everything in a a line, including whitespace characters.
getline(cin, phrase);
When you call cin >> phrase;, it only reads the string up to the first non-space character. If you want to include spaces in your name, best goes with getline(cin,phrase);.
IMPORTANT: getline() will reads whatever it is in the stream buffer up to the first \n. It means that when you enter cin >> greeting;, if you hit ENTER, getline() will read everything before that \n that is not already read, which is NOTHING into your phrase variable, making it an empty string. An easy way out is to call getline() twice. E.g.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
cout << "Exercise 3B" << endl;
cout << "Kaitlin Stevers" << endl;
cout << "String arrays" << endl;
cout << endl;
cout << endl;
char greeting[26];
cout << "Please enter a greeting: " << endl;
cin >> greeting; //IMPORTANT: THIS ASSUME THAT GREETING IS A SINGLE WORD (NO SPACES)
cout << "The greeting you entered was: " << greeting << endl;
string phrase;
cout << "Enter your full name " << endl;
string rubbish_to_be_ignored;
getline(cin,rubbish_to_be_ignored); //this is going to read nothing
getline(cin, phrase); // read the actual name (first name and all)
cout << greeting << ", how are you today " << phrase << "?" << endl;
return 0;
}
Assuming you store that code in the file stackoverflow.cpp. Sample run:
Chip Chip#04:26:00:~ >>> g++ stackoverflow.cpp -o a.out
Chip Chip#04:26:33:~ >>> ./a.out
Exercise 3B
Kaitlin Stevers
String arrays
Please enter a greeting:
Hello
The greeting you entered was: Hello
Enter your full name
Kaitlin Stevers
Hello, how are you today Kaitlin Stevers?
Tested on ubuntu 14.04

Problems with getline() function? [duplicate]

This question already has answers here:
getline not asking for input? [duplicate]
(3 answers)
Closed 8 years ago.
I have a problem with the getline function in the code below. In the "get" info section I want to be able to store a whole sentence, but I can't make it work.
When I open up my program it just skips the input for the info.
p.s: I'm new to C++
Here is the section of the code where i have the problem (Enter the information):
void add() {
string name;
string faction;
string classe;
string race;
string info;
ofstream wowdatabase("wowdatabase.txt", ios::app);
cout << "Add a race or class" << endl;
cout << "---------------------------------------------------------" << endl;
cout << "" << endl;
cout << "Enter the name of the race or class (only small letters!):" << endl;
cin >> name;
cout << "Enter Race (Type -, if writen in name section):" << endl;
cin >> race;
cout << "Enter Class (Type -, if writen in name section):" << endl;
cin >> classe;
cout << "Enter faction (Alliance/Horde):" << endl;
cin >> faction;
cout << "Enter the information:" << endl;
getline(cin, info);
wowdatabase << name << ' ' << faction << ' ' << classe << ' ' << race << ' ' << info << endl;
wowdatabase.close();
system("CLS");
main();
}
Now it works fine =) but, when i want to output the info again it only shows the first word in the sentence?
Before this statement
getline(cin, info);
make the following call
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
To use this call you must include header <limits>.
The problem is that after executing statement
cin >> faction;
the new line character that corresponds to enetered key ENTER is in the input buffer and the next getline call reads this character.
After you read fraction an empty line character will be left over. The consequent call to getline will read it. To avoid that add a call to cin.ignore before the getline call.

Clearing a carriage return from memory in C++

I have the following code:
int main()
{
// Variables
char name;
// Take the users name as input
cout << "Please enter you name..." << endl;
cin >> name;
// Write "Hello, world!" and await user response
cout << "Hello, " << name << "!" << endl;
cout << "Please press [ENTER] to continue...";
cin.get();
return 0;
}
After the user hits return to enter their name, that carriage return is carried forward to the end of the code where it is immediately applied as input to cin.get(), thus ending the program prematurely. What can I place on the line immediately following
cin >> name;
to stop this from happening? I know that it's possible, as I've done it before, but can't remember what it is or where I can find it. Thanks a lot in advance.
Really you want to use everything on the input upto the newline as the name.
Currently your code only reads the first word.
#include <iostream>
#include <string>
int main()
{
// Variables
std::string name;
// Take the users name as input
// Read everything upto the newline as the name.
std::cout << "Please enter you name..." << std::endl;
std::getline(std::cin, name);
// Write "Hello, world!" and await user response
// Ignroe all input until we see a newline.
std::cout << "Hello, " << name << "!\n";
std::cout << "Please press [ENTER] to continue..." << std::flush;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
}
simplest answer:
int main()
{
// Variables
char name;
// Take the users name as input
cout << "Please enter you name..." << endl;
cin >> name;
cin.get(); // get return here
// Write "Hello, world!" and await user response
cout << "Hello, " << name << "!" << endl;
cout << "Please press [ENTER] to continue...";
cin.get();
return 0;
}
You can tell your stream to ignore the next N characters with
cin.ignore(1000, '\n');
This will cause cin to skip up to 1000 characters or until it found (and removed) a newline ('\n') character. Other limits or terminating characters can be specified as you desire.
cin ignores the carriage return, the value before '\n' is stored in the variable and '\n' remains in the input stream. When cin.get() is called, it takes the value already in the input stream (which is '\n') and and thus it gets skipped.
To avoid this situation Tim's answer is perfect!
cin >> name;
cin.get(); // get return here
Alternatively you can also do
(cin >> name).get(); // get return as soon as cin is completed.
UPDATE : As pointed out by Loki Astari, When using cin>> operator to the array name, it will read up to the first white space character. In 'Tim Hoolihan' there is a space between the names. Thus name array will store {'T','i','m','\n'} as the value, '\n' marking an end to the string. One should avoid using char array for strings, instead use the class string from #include<string> header file. A string can contain white space character in between, whereas an array can't.
#include<iostream>
#include<string>
int main()
{
string name; // string is a class, name is the object
cout << "Please enter you name..." << endl;
(cin >> name).get();
cout << "Hello, " << name << "!" << endl;
// String using the "power" of an array
cout << "First two characters of your name are " << name[0] << name[1] << endl;
cout << "Please press [ENTER] to continue...";
cin.get();
return 0;
}
First of all name is a string and you are reading it in a char.
char name;
should be
string name;
Also add #include<string>
Now to clear the newline from the buffer you can do:
std::cin.ignore(1);
after reading the name.