Difference between cin and cin.get() for char array - c++

I have these 2 codes:
char a[256];
cin>>a;
cout<<a;
and
char a[256];
cin.get(a,256);cin.get();
cout<<a;
and maybe, relative to the second one without cin.get();
char a[256];
cin.get(a,256);
cout<<a;
My question is (first one) : for a char array, what should i use? cin or cin.get()? And why should i use cin.get(); with no parameter after my char initialisation?
And my second question is: my c++ teacher taught me to use every time cin.get() for initialisation chars and AFTER every initialisation char array or int array or just int or whatever, to again put cin.get(); after it. That's what i wanted to ask initially.
So, now i got these 2:
In this case, without cin.get() after the integer initialisation, my program will break and i can't do anymore my char initialisation.
int n;
cin>>n;
char a[256];
cin.get(a,256); cin.get(); // with or without cin.get();?
cout<<a;
And the correct one:
int n;
cin>>n; cin.get();
char a[256];
cin.get(a,256); cin.get(); // again, with or without?
cout<<a;
So, what's the matter? Please someone explain for every case ! Thank you.

They do different things, so choose whichever does what you want, or the better alternatives given below.
The first cin>>a; reads a single word, skipping over any leading space characters, and stopping when it encounters a space character (which includes the end of the line).
The second cin.get(a,256);cin.get(); reads a whole line, then consumes the end-of-line character so that repeating this will read the next line. cin.getline(a,256) is a slightly neater way to do this.
The third cin.get(a,256) reads a whole line but leaves the end-of-line character in the stream, so that repeating this will give no more input.
In each case, you'll get some kind of ill behaviour if the input word/line is longer than the fixed-size buffer. For that reason, you should usually use a friendlier string type:
std::string a;
std::cin >> a; // single word
std::getline(std::cin, a); // whole line
The string will grow to accommodate any amount of input.

The problem, most likely, is in the way you enter the values later on. The cin.get() after every initialization is there to "grab" the newline character that gets put in the stream every time you press enter.
Say you start entering your values like this:
2
a b c d...
Assuming you have pressed enter after 2, the newline character was also put on the stream. When you call cin.get() after that, it will grab and discard the newline character, allowing the rest of your code to properly get the input.
To answer your first question, for an array, you should use cin.get instead of the overloaded operator >> cin>> as that would only grab a single word, and it would not limit the amount of characters grabbed, which could lead to an overflow and data corruptions / program crashing.
On the other hand, cin.get() allows you to specify the maximum number of characters read, preventing such bugs.

For a char array use cin.get() because it counts whitespace whereas cin does not. More importantly, cin.get() sets the maximum number of characters to read. For example:
char foo[25]; //set maximum number of characters
cout << "Please type in characters for foo" << endl;
cin.get(foo,25);
cout << ' ' << foo;
In this case, you can only type in 24 characters and a null terminator character \0.
I hope this answers your first question.
I would personally use a string.

Related

Enter character instead int C++

I am writing a code that tally when an integer data type or character is entered.
int numero,
countInteger = 0;
countCharacter = 0;
while ( 1 ) {
try {
cin >> numero;
cout << numero;
throw numero;
} catch (...) {
countCharacter++;
cout << "Error";
}
}
If I entered Integer, counter in "countInteger" (but not show it in the code). If I enter a character, it is aa exception and recorded in "countCharacter".
But when I run the code generates an infinite loop and does not allow me to re-enter again. They could help me please. Guide me, you may have a bad concept.
When you try to read an integer, and you give something that's not an integer as input, there are two things happening: The first is that the stream gets its failbit set, the second things that happens is that the input is not extracted. So next iteration you read the same input again, and again and again...
I suggest another tactic: Read as a character, then see if it is a digit, an alphabetic character, or something else completely. Optionally, if you need the actual full number, read as a string, and try to convert to an integer.
A clarification: Input using std::cin is buffered. When you use the input operator >> then std::cin extracts characters from the buffer. If you try to read a number, but the first character in the buffer is not a digit, then the input operator will fail, and leave the character in the buffer.
Simple (hopefully) example:
Lets say you have this code
int number;
std::cin >> number;
std::cin >> number;
std::cin >> number;
As input for that part of the code, you enter
123abc
The first input will read 123 from the input, and stop at the letter, leaving the input as
abc
Now we come to the second input, and the code will see that the first character is not a digit, so it will set the failbit in the stream and leave the input as is:
abc
Then with the third input, the exact same thing as in the second happen.
Now imagine this was in a loop instead, the input operator >> will iteration after iteration see the non-digit input an promptly return, effectively giving you an infinite loop.
Now for a clarification of my suggestion... Depending on the goals and requirements of the program, you can instead read into a character and use the character classification functions to see what types you have.
Something like
int countDigit = 0;
int countCharacter = 0;
char ch;
while (std::cin >> ch)
{
if (std::isdigit(ch))
++countDigit;
else if (std::isalpha(ch))
++countCharacter;
else
{
// Not a digit or an alphabetic character
// I.e. newlines, spaces, control characters, etc.
}
}
Finally a note about using exceptions for this: Most people would consider it bad. Exceptions are for exceptions, exceptional cases, not as part of the normal flow of the program. Throwing an exception is expensive and disrupts the normal flow. Only use them for exceptional things, like errors.

cin.getline(char, int) gets skipped when in a loop

This is the code I have been trying to execute on TurboC++ 3.0 (Yes, I know it's ancient but can't help it), when the program goes into the loop, it skips the value of y every time including the first attempt. Any help would be appreciated but please avoid rubbing salt into wounds by asking why TurboC++ 3.0. Thanks in advance.
void main()
{
int x, z;
char y[10];
for (int i=0;i<5;i++)
{
cout<<"\nX:";
cin >> x;
cout<<"\nY:";
cin.getline(y,10);
cout<<"\nZ:";
cin>>z;
}
for(i=0;i<5;i++)
{
cout<<x<<"\n";
cout.write(y, 10)<<"\n";
cout<<z<<"\n\n";
}
}
and even if I use cin.get(var) where var is a character, i still get weird results like a heart, diamond or even a smiley.
You get weird results because you are not terminating your c style string with a null character.('\0').
The problem you are facing is because , fail bit or eof bit is set. To remove that, do the following:-
You can use
cin.clear() ;
to clear if any error bits are set and then use
cin.ignore(100, '\n') ;
// 100 is just a random no, change it depending on your size of input.
to ignore any irrelevant characters int the stream.
or you can do the following:-
after cin>>x just type cin.ignore(), it will flush out any newline characters present in the buffer .
it skips the value of y
cin >> x reads the input until it finds something that's not a digit - in this case, the end-of-line character. That character is left in the stream.
getline reads the input until it finds an end-of-line character (or the end of the stream). Since you've left one in the stream, it finds it straight away and doesn't read anything.
You can call cin.ignore(-1,'\n') to ignore the remainder of the first line after reading x (assuming your prehistoric library behaves like the modern one).
i still get weird results like a heart, diamond or even a smiley
cout.write(y, 10) is wrong - there are up to 9 valid characters in y, followed by the null terminator. You want cout << y to treat it as a null-terminated string and print only the valid characters.

My code is written twice for uncomprehensible reasons

This code is written in C++ and for reasons that I don't quite understand it is written twice.
I would expect that after inputting a random char it would display the char once and the String lower to it once as well. But I don't get this as output. What am I missing?
Solution: Adding a cin.ignore() statement disregards the return that is read in as well.
Making my code go through the loop once.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
char letter;
letter = cin.get();
while (letter!= 'X')
{
cout << letter << endl;
cout << "this will be written twice for ununderstandable reasons";
letter = cin.get();
}
}
Example:
If I were to write in cmd scrn c, I'd get a c back + twice the phrase this will be written twice for ununderstandable reasons. So what I thought to be the output
c
this will be written twice for ununderstandable reasons
is actually
c
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
as everyone already mentioned, cin will append the newline marker \n every time you hit enter. another solution is to place cin.ignore(); after every cin.get();.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
char letter;
letter = cin.get();
cin.ignore();
while (letter!= 'X')
{
cout<<letter<<endl;
cout<<"this will be written twice for ununderstandable reasons";
letter= cin.get();
cin.ignore();
}
}
You are reading every character with the unformatted get() function, including the newline character each time you hit return.
Depending on what you're trying to do, you could use formatted input (cin >> c) to skip all whitespace; or you could test each character and ignore things like newline that don't interest you; or you could use getline(cin, some_string) to read a whole line, and then process that.
When you type in a character the new-line character (from pressing enter) is also in your input buffer.
From the C-Reference:
The delimiting character is not extracted from the input sequence if found, and remains there as the next character to be extracted from the stream (see getline for an alternative that does discard the delimiting character).
Just use a cin.sync() after every cin.get() to clear the buffer and you should be good to go.
You forgot about the newline.
cin reads every character, which includes the newline you type after typing your character.
If you don't want this behaviour, you have to specifically check for newline.
while (letter!= 'X')
{
if (letter == '\n')
{
letter = cin.get();
continue;
}
cout<<letter<<endl;
cout<<"this will be written twice for ununderstandable reasons";
letter= cin.get();
}
The text 'this will be written twice..' will not necessarily print twice.
Type 'qwerty' + ENTER and your stream will have "qwerty\n" within and you'll see this output:
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
Exactly that many as string "qwerty\n" has characters.
The problem is that
cin.get()
Puts all chars that you type into a stream/buffer (not your letter char) but handles one char every cin.get() invocation.
When you type 'abcXd' + enter - the program will print above line 3 times and stop on X.
It happens because cin.get() reads new-line character too. Try to press Enter without any symbols or type some string, like abc.
You need to handle it, e.g.:
while (letter = cin.get()) {
if (!isalpha(letter)) { continue; }
// handling user inputted alpha
}

Line Breaks when reading an input file by character in C++

Ok, just to be up front, this IS homework, but it isn't due for another week, and I'm not entirely sure the final details of the assignment. Long story short, without knowing what concepts he'll introduce in class, I decided to take a crack at the assignment, but I've run into a problem. Part of what I need to do for the homework is read individual characters from an input file, and then, given the character's position within its containing word, repeat the character across the screen. The problem I'm having is, the words in the text file are single words, each on a different line in the file. Since I'm not sure we'll get to use <string> for this assignment, I was wondering if there is any way to identify the end of the line without using <string>.
Right now, I'm using a simple ifstream fin; to pull the chars out. I just can't figure out how to get it to recognize the end of one word and the beginning of another. For the sake of including code, the following is all that I've got so far. I was hoping it would display some sort of endl character, but it just prints all the words out run together style.
ifstream fin;
char charIn;
fin.open("Animals.dat");
fin >> charIn;
while(!fin.eof()){
cout << charIn;
fin >> charIn;
}
A few things I forgot to include originally:
I must process each character as it is input (my loop to print it out needs to run before I read in the next char and increase my counter). Also, the length of the words in 'Animals.dat' vary which keeps me from being able to just set a number of iterations. We also haven't covered fin.get() or .getline() so those are off limits as well.
Honestly, I can't imagine this is impossible, but given the restraints, if it is, I'm not too upset. I mostly thought it was a fun problem to sit on for a while.
Why not use an array of chars? You can try it as follow:
#define MAX_WORD_NUM 20
#define MAX_STR_LEN 40 //I think 40 is big enough to hold one word.
char words[MAX_WROD_NUM][MAX_STR_LEN];
Then you can input a word to the words.
cin >> words[i];
The >> operator ignores whitespace, so you'll never get the newline character. You can use c-strings (arrays of characters) even if the <string> class is not allowed:
ifstream fin;
char animal[64];
fin.open("Animals.dat");
while(fin >> animal) {
cout << animal << endl;
}
When reading characters from a c-string (which is what animal is above), the last character is always 0, sometimes represented '\0' or NULL. This is what you check for when iterating over characters in a word. For example:
c = animal[0];
for(int i = 1; c != 0 && i < 64; i++)
{
// do something with c
c = animal[i];
}

How do I input variables using cin without creating a new line?

Whenever I input a variable using cin, after one hits enter it automatically goes to a new line. I'm curious if there's a way to use cin without having it go to a new line. I'm wanting to cin and cout multiple things on the same line in the command prompt. Is this possible?
You can't use cin or any other standard input for this. But it is certainly possible to get the effect you are going for. I see you're on Windows using Visual Studio, so you can use, for example, _getch. Here's an example that reads until the next whitespace and stores the result in a string.
#include <conio.h> // for _getch
std::string get_word()
{
std::string word;
char c = _getch();
while (!std::isspace(c))
{
word.push_back(c);
std::cout << c;
c = _getch();
}
std::cout << c;
return word;
}
It's not very good. For example, it doesn't handle non printing character input very well. But it should give you an idea of what you need to do. You might also be interested in the Windows API keyboard functions.
If you want a wider audience, you will want to look into some cross-platform libraries, like SFML or SDL.
you can also use space for input instead of enter
something like this:
cin >> a >> b >> c;
and in input you type
10 20 30
then
a=10
b=20
c=30
As others have noted, you can't do this with cin, but you could do it with getchar(). What you would have to do is:
collect each character individually using getchar() (adding each to the end of a string as it is read in, for instance), then
after reading each character, decide when you've reached the end of one variable's value (e.g. by detecting one or more ' ' characters in the input, if you're reading in int or double values), then
if you've reached the end of the text for a variable, convert the string of characters that you've built into a variable of the appropriate type (e.g. int, double, etc.), then
output any content onto the line that might be required, and then
continue for the next variable that you're reading in.
Handling errors robustly would be complicated so I haven't written any code for this, but you can see the approach that you could use.
I don't think what you want to do can be achieved with cin. What you can do is to write all your input in one line, with a delimiter of your choosing, and parse the input string.
It is not possible. To quote #Bo Persson, it's not something controlled by C++, but rather the console window.
I can't comment but if you leave spaces between integers then you can get the desired effect. This works with cin too.
int a, b, c;
cin>>a; cin>>b; cin>>c;
If you enter your values as 10 20 30 then they will get stored in a, b, and c respectively.
just use the gotoxy statement. you can press 'enter' and input values in the same line
for eg. in the input of a 3*3 matrix:
#include<iostream.h>
#include<conio.h>
void main()
{clrscr();
int a[20][20],x,y;
cout<<"Enter the matrix:\n ";
for(int r=2;r<7;r+=2)
for(int c=2;c<7;c+=2)
{gotoxy(c,r);
cin>>a[r][c];
}
getch();}