Difference between getline() and get()?

  • Thread starter proton
  • Start date
  • Tags
    Difference
In summary: However, str does not contain the character '!' because it is a delimiter, and getline does not extract it.
  • #1
proton
350
0
I'm taking c++ and I'm having difficulty differentiating the two. My lecturer and textbook don't explain these well.

My lecture notes says that for getline:
"if the delimiter is found it is extracted but not stored. Use get() if you don't want this character to be extracted"

What does it mean by "extracted" or "stored"?

one of the examples the instructor provided was:

int main()
{
cout << "What year was your house built?\n";
int year;
cin >> year;
cout << "What is its street address?\n";
char address[80];
cin.getline(address,80);
cout << "Year built:" << year << "\n";
cout << "Address: " << address << "\n";
cout << "Done!\n";
return 0;
}

the output is:
What year was your house built?
1966
What is the street address?
Year built: 1966
Address
Done!

Now the book says that street address was skipped because cin.getline reads the newline and replacing it with get() will fix it since get() discards the newline. What does this have to do with extracting and storing?


I had another off-related question: With regards to abstract classes, what does instantiate mean? I understand how abstract classes work, but I don't understand how they can't "instantiate" objects
 
Technology news on Phys.org
  • #2
I have a final tomorrow. Can anyone help?
 
  • #3
Hello proton

I know its too late for you, but still I am posting my answer.

You must have seen that when you try to play a song or a movie clip on the net, there is always a line at the bottom of the player: "Buffering 1%" or "buffering 70%" or whatever. What is buffering and why is it done?

When a movie or a song has to be played, it requires quick processing of large chunks of data. You must have noticed the speed of movie play (like 300 kbps, which means that 300 KB of data is being processed per second to play that movie/song). Now it really depends on your internet connection speed as to how much data is being tansmitted to your computer. If your connection speed is low, data will not be transmitted at a sufficiently high speed and there will be frequent stoppages in the song/movie. The quality of the movie/song also degrades. And that, as we all know, is VERY, VERY frustrating.
So, to keep these stoppages to the minimum, buffering is done. What this means is that at the start, instead of playing the song/movie immediately,
the media plyer first secures a part of your memory(RAM). This part of memory secured by the player is called the "buffer". The player then stores the song in the buffer until the buffer is full ("buffering 100%). As soon as the buffer is full, the CPU now uses data from the buffer and plays the song/movie, while the buffer refills itself. By the time movie/song stored in first buffering is complete, the buffer (usually) has already filled itself again, and starts providing data immediately. Thus, there are no breaks in the movie and the whole movie/song is played smoothly due to buffering (this is not the case when your connection speed is extremely low, because buffering also requires time, and if previous buffering has ended before the buffer could refill itself completely, the movie breaks till the time buffering is complete).

So, a buffer is a memory place where data is temporarily stored before it reaches its destination, so that flow of data is smooth and non-stop.

...continued
 
  • #4
In C++ also, before any data is actually transferred from one place to another, it first goes into a buffer.
When you write:

char a[5];
cin>>a; //I type "groan" and press enter

Obviously, the program will assign "groan" to a. Let us see, how it happens:

1. Both the string "groan" and '\n' (because I pressed enter) go into the buffer (called input stream buffer).
2. the '>>' operator then reads each character of the string entered ("groan") from the buffer and then removes it from the buffer. In other words, '>>' "extracts" each character from the buffer, and stores it in the array 'a' sequentially .
3. Here, cin is followed by '>>', which means all whitespaces in the buffer are skipped/ignored: they are not stored in a.
4. Since '\n' is also a whitespace, it is skipped, and thus it is not "extracted", it remains behind in the buffer.

continued...
 
Last edited:
  • #5
Now let's move to your problem:

Now the book says that street address was skipped because cin.getline reads the newline...

Let us discuss cin.getline().

If I write:

char str[5];
getline(str,5,'#');

First, note that I have given three arguments, instead of the usual two.
This is because the third argument is optional. The character I have entered is called a "delimitror". You can enter any other character here, whichever you want. e.g.

getline(str,5,'a');
or
getline(str,5,'\n'); etc.

What does a delimitor mean. Just look at the following codes:
1.
char str[5];
getline(str,5,'#'); //Suppose I enter: "com#!t"
cout<<str; //output: com

2.
char str[5];
getline(str,5,'o'); //I enter: com#!t"
cout<<str; //output: c

3.
char str[5];
getline(str,5,'!'); //I enter: com#!t"
cout<<str; //output: com#

4.
char str[5];
getline(str,5,'t'); //I enter: com#!t"
cout<<str; //output: com#!

So, what do you notice? Yes, str contains only those characters which come before the character I have specified in getline().

continued...
 
  • #6
This is what happened:
1. The string "com#!t" goes into the input stream buffer. This time cin is not followed by '>>' but rather by a function getline().
getline() says that copy(or store) those characters into str which come before the delimitor. As soon as delimitor is encountered, stop reading more characters even if the length (5 in our case) is not completed.

2. See code number 1, where the delimitor is '#'
Here, the getline() function first goes to 'c' and checks whether it matches with '#'. No. Pass it to str (i.e. "extract" 'c'). Then go to next character 'o'. Check with '#'. Doesn't match. Pass it to str. Same with 'm'. Now comes '#'. Match found. Do not pass to str, but extract it all the same. Remember what I said: extraction of a charcater means it is removed from the buffer. So, '#' is removed from the buffer. As already told, the reading process stops then and there.
str now contains "com". '\0' is added to it and in this way, str is assigned a string: "com". That's why the output is "com".

Let's now go to your code:

cout << "What year was your house built?\n";
int year;
cin >> year;
cout << "What is its street address?\n";
char address[80];
cin.getline(address,80);
cout << "Year built:" << year << "\n";
cout << "Address: " << address << "\n";
cout << "Done!\n";

Let us check line by line:

cin >> year;

Suppose I enter 1990, and press enter.
Suppose input buffer was empty initially. Now it contains 1990 and '\n' (I pressed enter). The value 1990 will be "extracted" from the buffer by storing it in year. As already told, '\n' will remain behind in the buffer.
Now when you write,

cin.getline(address,80);

we expect the program to halt and accept the address. But this doesn't happen. Why? Because there is already data present in the buffer: '\n'. And '\n' is the default delimitor of getline(). Thus, why should getline read any data from the keyboard when it has already found its delimitor. Therefore, we need to throw '\n' out of the buffer before we can make getline() read any more data.

continued...
 
Last edited:
  • #7
One solution is to change the delimitor explicitly:for example, you could write something like:

cin.getline(address,80,'#');

Now the program will halt and wait for you to type the address before proceeding any further, because '\n' is no more its delimitor and it will only stop if it has found '#' or 80 letters are read.

Personally, I don't think that using cin.get() instead of cin.getline() is going to help (you can try it yourself). So the best solution, I think, is the one I have given above.

_____________________________________________________________________________
EDIT (8-20-2007): Er, actually your textbook is right, because get() function is actually overloaded (i.e. there are more than one get() functions, distinguished by their args). The one your textbook is talking about is the get() function which accepts a single character, not a string. So, as I told you that when you used cin>>year, '\n' was left in the buffer. If you insert these two lines of code just after the cin statement, your program will work perfectly.

char ch;
cin.get(ch); // '\n' will go into ch, and buffer will be emptied, ready to accept address

______________________________________________________________________________


The difference between get() and getline() is that when getline() encounters the delimitor, it "extracts" it(removes it from the buffer) before stopping reading, whereas when cin.get() encounters a delimitor, it does not extract it, and therefore, like cin>>, cin.get() also leaves behind the delimitor in the buffer. Otherwise, both functions are perfectly identical: You could have as easily written: cin.get(address, 80, '#'); No problem with it.


Oh my gosh! My fingers are aching with all this typing. I hope my long long post helped. Forgive me for any spelling mistakes.

Warm regards
Mr V

P.S. You must be wondering why I posted my answer in parts. Because when I tried to post it as a whole, the PF database crashed (I think so) for a while.
I don't want to repeat that mistake and get kicked out of the forum, do I ?!
 
Last edited:
  • Like
Likes Mr Real
  • #8
Apparently my-virtual has done a great job explaining buffer and extracting. However, given the context of the problem, the best solution to the original problem is to add a line of code :
cin >> year;
/*************added line**********
cin.get();
************/
cout << "What is its street address?\n";
char address[80];
cin.getline(address,80);

This way, get() will extract the '\n' in the buffer, now you can type the address. Here you can not use getline() because it is not defined.

Sorry to reply such an old post. I just want the truth to be shown.
 
  • #9
Excellent explanation. I have one question:

If >> discards '/n' from the buffer why:
cout<<"Write your age: ";
cin>>age;
cout<<"Write whatever: ";
cin>>whatever;
cout<<"Write etc...";
cin>>etc;

works perfectly?
 
  • #10
What do you mean by "works perfectly"?

What if I write "xx years and yy months" in response to write your age?
 

What is the difference between getline() and get()?

getline() is a function that reads a line of input from a file or standard input and stores it as a string, while get() reads a single character from a file or standard input and returns it as an integer.

Can getline() and get() be used interchangeably?

No, they cannot be used interchangeably. getline() is used for reading strings, while get() is used for reading single characters.

In what situations would you use getline() over get()?

getline() is commonly used when reading input from a user or a file that contains multiple lines of text, whereas get() is more suitable for reading single characters or parsing through a file with known formatting.

What happens if getline() and get() are used together?

If used together, getline() will read the remaining characters from the current line and get() will read the first character of the next line. This can lead to unexpected results and should be avoided.

Are getline() and get() part of the standard C++ library?

Yes, both getline() and get() are part of the <iostream> standard library in C++ and can be used in any C++ program.

Similar threads

  • Programming and Computer Science
Replies
8
Views
2K
Replies
10
Views
905
  • Programming and Computer Science
Replies
6
Views
1K
  • Programming and Computer Science
3
Replies
75
Views
4K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
33
Views
6K
  • Programming and Computer Science
Replies
6
Views
3K
  • Programming and Computer Science
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
634
  • Engineering and Comp Sci Homework Help
Replies
6
Views
2K
Back
Top