Thread: Expected output is missing from using fgets()

  1. #1
    Registered User
    Join Date
    Feb 2017
    Posts
    14

    Expected output is missing from using fgets()

    Hi all, new to the forum

    Just wanted some assistance: does anyone know why the first word of the string isn't printed in the output when i use 'fgets()' in the code (below) and what can I do to solve this issue?

    Thanks in advance.

    Code:
    #include <iostream>
    #include <cstdio>
    
    
    using namespace std;
    
    
    int main()
    {
    	char str[40]; // Holds ten characters with a null (0) at the end.
    
    
    		cout << "Enter a string: ";
    		cin >> str; //read string from keyboard
    		cout << "Here is your string: " << endl;
    		fgets(str, 40, stdin);
    			cout << str << endl;
    		return 0;
    }
    Output: Expected output is missing from using fgets()-capture-png

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Because cin >> str; is like scanf("%s") in C.
    It uses white-space as a delimiter.

    If you want to read a whole line in C++, then use cin.getline()
    Also in C++, use std::string to store things, not char arrays.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Mingling C and C++ I/O is a bad idea. It didn't bite you this time, but it's just better not to do it.

    What happened here is this: std::istream::operator>> reads until the first delimiter (any whitespace). So on line 14, you get one word. The following space is left in the input buffer, and then, on line 16, you read the remainder, up to 40 characters, starting at the beginning of your buffer (str), and overwriting what you just read on line 14.

    You also have a recipe for undefined behavior here, because you allocate enough space for 40 characters, and then you tell fgets to read up to 40 characters into a buffer, and then print that buffer. The problem comes if there are actually 40 characters to read, in which case there will be no null terminator. When you print it back out, std::ostream::operator<< will try to print until it finds the null terminator, which could be anywhere, even outside the allocated space for your program, or nowhere at all, causing your program to crash.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > The problem comes if there are actually 40 characters to read, in which case there will be no null terminator.
    This isn't true.
    fgets() always appends a \0.
    It leaves the rest of the input on the input stream.
    fgets(3): input of char/strings - Linux man page
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is that the formatted input with the overloaded operator>> leaves the trailing whitespace in the input buffer. If this whitespace includes a newline, then subsequently reading up to the end of the line as with fgets would give you what appears to be an empty (or only consisting of whitespace) string.

    There are two general approaches to fixing this:
    • Read line by line, parsing the line if necessary. This approach could be easier if you used std::string instead with std::getline.
    • Discard characters after reading with operator>> until the newline is encountered, e.g., by using cin.ignore


    By the way, instead of using fgets, use cin.getline to read the line. fgets is inherited from the C standard library, whereas cin.getline would be more consistent with what you have been using for I/O.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Feb 2017
    Posts
    14
    Overwhelmed by all your responses, read through them and got the code sorted. Now understanding it a bit more. Thanks for the help all.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. output value not as expected @beginner
    By nmn in forum C Programming
    Replies: 10
    Last Post: 03-20-2013, 03:55 PM
  2. Replies: 2
    Last Post: 04-06-2012, 02:12 PM
  3. Not getting expected Output
    By ldysmann in forum C++ Programming
    Replies: 5
    Last Post: 02-08-2012, 04:40 AM
  4. non expected output
    By c++.prog.newbie in forum C Programming
    Replies: 2
    Last Post: 09-27-2004, 05:41 PM
  5. Missing Output
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 11-30-2001, 01:16 AM

Tags for this Thread