confusing syntax of cin.get() - c++

I read a book which mentions that cin.get() will keep delimiter in the input stream, thus, the result of a following consecutive calling with the same delimiter is an empty line. So I wrote the following code to test this property and other.
#include <iostream>
using namespace std;
int main()
{
char array[10];
int character;
cin.get(array, 10, 'a');
cout << endl << array << endl;
cout << cin.eof() << endl;
cin.get(array, 10, 'a');
cout << "not ignored: " << array << endl;
cin.ignore();
cin.get(array, 10,'a');
cout << "ignored: " << array << endl;
while((character=cin.get())!=EOF){}
cout << character << endl;
cout << cin.eof() << endl;
}
I then type in "Miami is a city(Enter)" in the terminal, get the following results:
Mi
0
not ignored:
ignored:
-1
0
I don't make sense several points. I didn't input ‘EOF’, but the character holds value of '-1'. I guess it might be that the second cin.get(array, 10, 'a'); get an empty line, it just views it as ‘EOF’? Am I right? If so, it makes sense that no other chars follows "ignored:". But if so, why the last statement print out '0'? Thanks!

From http://en.cppreference.com/w/cpp/io/basic_istream/get
If no characters were extracted, calls setstate(failbit). In any case, if count>0, a null character (CharT() is stored in the next successive location of the array.
Since, no characters were extracted in the second call
cin.get(array, 10, 'a');
failbit was set. You'll have to clear the state before you can read more characters from the string.
Working code:
#include <iostream>
using namespace std;
int main()
{
char array[10];
int character;
cin.get(array, 10, 'a');
cout << endl << array << endl;
cout << cin.eof() << endl;
cin.get(array, 10, 'a');
// failbit is set since no characters were extracted in the
// above call.
cout << "not ignored: " << array << endl;
// Clear the stream
cin.clear();
cin.ignore();
cin.get(array, 10,'a');
cout << "ignored: " << array << endl;
while((character=cin.get())!=EOF){}
cout << character << endl;
cout << cin.eof() << endl;
}

Related

seekg() before each .get() call VS seekg() before for loop

I am just trying to read simple text file with ifstream. Suppose my text file looks like this (I don't know how to properly format it here, so here is how I wrote it notepad):
a\tb\nc\t\d\n
Output from reading text file using .seekg() before each .get() differs from output when .seekg() is called only before for loop (see output).
Question:
Is this expected behaviour? If yes then why is it happening?
Code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream myfile("test.txt");
if (myfile)
{
cout << "Using seekg before each myfile.get():" << endl;
cout << "***********************" << endl;
myfile.seekg(0);
cout << (char)myfile.get();
myfile.seekg(1);
cout << (char)myfile.get();
myfile.seekg(2);
cout << (char)myfile.get();
myfile.seekg(3);
cout << (char)myfile.get();
myfile.seekg(4);
cout << (char)myfile.get() << endl;
cout << "***********************" << endl;
cout << "Using seekg only before loop:" << endl;
cout << "***********************" << endl;
myfile.seekg(0);
for (int i = 0; i <= 4; i++)
{
cout << (char)myfile.get();
}
cout << endl;
cout << "***********************" << endl;
myfile.close();
}
}
Output:
Output after running above code
After debugging:
In text file:
a is at position 0
'\t' is at position 1
b is at position 2
when .seekg(3) is used right before .get() then .get() returns '\n'
when .seekg(4) is used right before .get() then .get() returns '\n' also
when .seekg(0) is used only before for loop (see code) then .get() only returns single '\n' at position 3/4 , meaning '\n' is at the position 3 and 'c' is at position 4

compiling is okay but my program doesn't really work

#include <iostream>
#include <string.h>
using namespace std;
int main()
{
while (1)
{
char name1[100];
char adrs1[100];
char rsn1[100];
char XXXXX[100];
cout << "input personal information" << '\n';
cout << "patient 1" << '\n';
cout << "input the name of the patient" << '\n';
cin.getline (name1,100);
cout << "input the address of the patient" << '\n';
cin.getline (adrs1,100);
cout << "input the reason" << '\n';
cin.getline (rsn1,100);
cout << "input the name of the patient" << '\n';
cout << "if you want to exit, input exit" << '\n';
cin.getline (XXXXX,100);
if (XXXXX==name1)
cout << adrs1[100] << rsn1[100] << '\n';
else (XXXXX=="exit");
break;
return 0;
}
}
that's my program, and compiling is okay. but when i start the program, it doesn't print any rsn or adrs, it just ends.
I want it to print rsn and adrs when it reads names.
Help me please
There are quite a few errors in your program.
The most important one is that you are trying to write an infinite loop. But it runs exactly once. You need to move your return statement out of the loop.
There is no need for a conditional statement for an else block. You can remove it along with the semi colon.
You're trying to print a character at the index 100 which goes out of bounds.
I don't know what XXXXX is supposed to be. May be you missed pasting the declaration on this website.
At this point, I really suggest picking up a book or trying to debug your code by going step-by-step through your code. It would be more helpful to you at this stage in your learning than this website,
To complete the answer above, the correct program would be:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
while (1)
{
char name1[100];
char adrs1[100];
char rsn1[100];
char XXXXX[100];
cout << "input personal information" << '\n';
cout << "patient 1" << '\n';
cout << "input the name of the patient" << '\n';
cin.getline (name1,100);
cout << "input the address of the patient" << '\n';
cin.getline (adrs1,100);
cout << "input the reason" << '\n';
cin.getline (rsn1,100);
cout << "input the name of the patient" << '\n';
cout << "if you want to exit, input exit" << '\n';
cin.getline (XXXXX,100);
if (strcmp(XXXXX,name1) == 0)
cout << adrs1 << rsn1 << '\n';
else /*(XXXXX=="exit");*/
break;
//return 0;
}
}
You forgot to initilize the name1 variable, you can initialize it using char name1[100] = {};
You cannot directly compare the if (XXXXX==name1), use can use the strncmp function for the same. I will prefer the string class instead of char pointer. Use the following:
if (!strncmp(XXXXX,name1,100))
cout << adrs1 << rsn1 << '\n';
else if (!strncmp(XXXXX,"exit",100))
break;

closing while(cin.good()) loop properly

I'm trying to make the program exit properly without it. I have '|' as my exit, if its the first thing I do when first running, it closes fine. But after entering values and printing them, afterwards entering '|' to exit.
It prints out:
"The smaller value is 0
The larger is previous second value" // want to remove this from showing
int main()
{
double first = 0, second = 0;
while(cin.good()){
char exit;
cout << "Enter '|' to exit.\n";
cout << "Enter two numbers:";
cin >> first >> second;
exit = cin.peek();
if(exit=='|'){
break;}
else{
if(first<second){
cout << "\nThe smaller value is " << first << "\nThe larger value is " << second << endl;
}
else if(first>second){
cout << "\nThe smaller value is " << second << "\nThe larger value is " << first << endl;
}
}
}
}
In your code, you've assumed that the input from your users will be limited to something usable as a double. This isn't necessarily the case. The issue that you're running into isn't related to the statement exit = cin.peak(); but to cin >> first >> second; You can test this by entering any non-numerical input into your program and watching it fail by assigning a 0 to the first and leaving second as is.
In short, because the conversion of the input into a double fails, you get an indeterminate value for first and then your program moves on.
You can use the following code as an example. In this, I first populate my variables as strings, then attempt a conversion after the fact.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
string str_first, str_second;
double first = 0, second = 0;
while(cin.good()){
cout << "Enter '|' to exit.\n";
cout << "Enter two numbers:";
cin >> str_first >> str_second;
if( (str_first.compare("|") == 0) || (str_second.compare("|") == 0) ){
cout << "\nThanks for playing\n" << endl;
break;}
else{
first = strtod (str_first.c_str(), NULL);
second = strtod (str_second.c_str(), NULL);
if(first<second){
cout << "\nFirst is small: The smaller value is " << first << "\nThe larger value is " << second << endl;
}
else if(first>second){
cout << "\nSecond is small: The smaller value is " << second << "\nThe larger value is " << first << endl;
}
}
}
}

Using cin.get() to discard unwanted characters from the input stream in c++

I am working on an assignment for my C++ class. The following code is given. The directions explain to enter a six character string and observe the results. When I do this, the second user prompt is passed over and the program ends. I am pretty certain the reason for this is that the first cin.getline() is leaving the extra character(s) in the input stream which is messing up the second cin.getline() occurrence. I am to use cin.get, a loop, or both to prevent the extra string characters from interfering with the second cin.getline() function.
Any tips?
#include <iostream>
using namespace std;
int main()
{
char buffer[6];
cout << "Enter five character string: ";
cin.getline(buffer, 6);
cout << endl << endl;
cout << "The string you entered was " << buffer << endl;
cout << "Enter another five character string: ";
cin.getline(buffer, 6);
cout << endl << endl;
cout << "The string you entered was " << buffer << endl;
return 0;
}
You are right. The newline character stays in the input buffer after the first input.
After the first read try to insert:
cin.ignore(); // to ignore the newline character
or better still:
//discards all input in the standard input stream up to and including the first newline.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
You will have to #include <limits> header for this.
EDIT:
Although using std::string would be much better, following modified code works:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
char buffer[6];
cout << "Enter five character string: ";
for (int i = 0; i < 5; i++)
cin.get(buffer[i]);
buffer[5] = '\0';
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << endl << endl;
cout << "The string you entered was " << buffer << endl;
cout << "Enter another five character string: ";
for (int i = 0; i < 5; i++)
cin.get(buffer[i]);
buffer[5] = '\0';
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << endl << endl;
cout << "The string you entered was " << buffer << endl;
return 0;
}

Difference between these two?

#include <cctype> // Character testing and conversion
using std::cin;
using std::cout;
using std::endl;
int main() {
char letter = 0; // Store input in here
cout << endl
<< "Enter a letter: "; // Prompt for the input
cin >> letter; // then read a character
if(std::isupper(letter)) { // Test for uppercase letter
cout << "You entered a capital letter."
<< endl;
cout << "Converting to lowercase we get "
<< static_cast<char>(std::tolower(letter)) << endl;
return 0;
}
if(std::islower(letter)) { // Test for lowercase letter
cout << "You entered a small letter."
<< endl;
cout << "Converting to uppercase we get "
<< static_cast<char>(std::toupper(letter)) << endl;
return 0;
}
cout << "You did not enter a letter." << endl;
return 0;
}
Here in this example, what is the difference between using 'std::' if(std::isupper(letter)) { and not using 'std::' if(isupper(letter)) {?
I tried both and they return the same result so I'm not sure what would be the benefit of using 'std::'
Posting namezero user comment:
without the std::, you'll call a function named isupper() from the current scope, and if there isn't any, from the global namespace (::isupper()). Writing std::isupper() refers to a function names isupper() in namespace std