istream question

This is a discussion on istream question within the C++ Programming forums, part of the General Programming Boards category; Hello all, so I am writing up a few programs according to the book. However I do not entirely get ...

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    110

    istream question

    Hello all, so I am writing up a few programs according to the book. However I do not entirely get what it is saying.

    Code:
    istream& read(istream& read, Student_info& student){
    	read >> student.name >> student.midterm >> student.final;
    
    	read_hw(read, student.homework);
    
    	return read;
    }
    Student_info is a data structure.

    I understand that it is taking in input from the istream and then storing into the data structure. However why is it that I must return "read"? Obviously the function has a return type of istream but what does returning "read" essentially do after I store all the input? The books speaks a little about the error state. What does this mean? Can't I just turn it into a void function and have it return nothing, as long as all my data gets stored into the correct data structure?

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,176
    What book is this? What page?

    Anyway, I'm fairly certain that will not compile. I imagine that the example from your book is very different. (I'm betting you've incorrectly meshed to functions together.)

    For this particular function, as you've posted it, returning `void' would be fine. However, if the function is really spelled `std::istream & operator (std::istream &, student_info &)' you must return the stream or you will break chaining. (You know how you can use multiple `<<' in the same `std::cout' line? They call that operator chaining.)

    Soma

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    One reason to return the stream is so you can use the same function to control looping:

    Code:
    int main()
    {
        std::vector<Student> students;
        Student input_student;
        ifstream fin("students.dat");
        while (read(fin, input_student)) {
            students.push_back(input_student);
        }
        //now all the data is in the vector, unless an error happened
    }
    Anyway, I'm fairly certain that will not compile.
    Why not?

    It is bad style to name functions and their arguments the same, but wouldn't the parameter shadow the function name which is not needed inside the function?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by anon View Post
    It is bad style to name functions and their arguments the same, but wouldn't the parameter shadow the function name which is not needed inside the function?
    I agree, so as long as you don't do this:
    Code:
    int fact(int fact)
    {
       if (fact > 1) return fact * fact(fact-1);
       else return 1;
    }
    That WILL NOT COMPILE, but the code posted above is bad style [1], but will compile in any compiler that follows the current or past C standards (some compilers MAY not do that, but all the "big" compilers do on this case at least).

    [1] And it's doubly bad style if it's in a book that is intended for people to learn from!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,176
    "Why not?"

    Habit. I use some extremely picky tools--which error on the shadowed entity name. I guess I'm just used to picky behavior.

    Soma

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    I apologize, but I renamed one of the argument variables as I was typing this up. I didn't realize it was the same name as the function. The book had it as "is" but sometimes I name whatever the book has differently just for my own understanding.

    Code:
    istream& read(istream& is, Student_info& student){
    	is >> student.name >> student.midterm >> student.final;
    
    	read_hw(is, student.homework);
    
    	return is;
    }

    May I ask how that would control the looping? When the istream runs out of input what does it exactly return? And what kind of errors would you come across?

    And are there other reasons?

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by dnguyen1022 View Post

    May I ask how that would control the looping? When the istream runs out of input what does it exactly return? And what kind of errors would you come across?

    And are there other reasons?
    It is quite typical that stream input functions return the same stream which in turn can be tested in boolean context (is stream good to continue after an attempt to input something?). Therefore it would be quite natural to make your own input routines also return the stream, so they can be used in the same way as for example getline.

    Typical errors that might happen is failure to open file, unexpected contents (trying to input a number but the file does not contain numeric data at that spot) and reaching the end of file. You can test these conditions with the eof(), fail() and rdstate() function.

    Example:
    Code:
    #include <iostream>
    #include <fstream>
    
    void test_io_flags(const char* filename, const char* contents)
    {
        std::ofstream fout(filename);
        fout << contents;
        fout.close();
        
        int n;
        std::ifstream fin(filename);
        while (fin >> n) {
            std::cout << "Read " << n << '\n';
        }
        std::cout << "eof() = " << fin.eof() << ", fail() = " << fin.fail() << "\n\n";
    }
        
    int main()
    {
        std::cout << std::boolalpha;
        const char* filename = "untitled1.tmp";
        test_io_flags(filename, "10 20 30"); //contains numbers as expected
        test_io_flags(filename, "5 hello 8"); //not all numbers, "corrupted" file contents
    }
    In the first test the file contains all numbers as expected. After everything is input both eof and fail bit are set: the entire file has been read and the last input attempt failed (because there was nothing more left to read).

    In the second test the file is "corrupt" containing a non-numeric string. This time eof bit is not set, meaning an input error happened before the entire contents could be read.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    Registered User
    Join Date
    Feb 2009
    Posts
    42
    That exercise is from Accelerated C++ if I recall correctly, and it returns a istream because of the way you use to call that function.

    You probably call the function with something like:

    Code:
    while (read (cin, x))
    where x would be a Student_Info you created to add to a vector or something.

    If it was type void, you wouldn't be able to loop it with while.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. another do while question
    By kbpsu in forum C++ Programming
    Replies: 3
    Last Post: 03-23-2009, 12:14 PM
  2. istream question
    By lord in forum C++ Programming
    Replies: 8
    Last Post: 11-13-2008, 03:31 PM
  3. ostream and istream
    By xddxogm3 in forum C++ Programming
    Replies: 2
    Last Post: 10-20-2003, 07:36 AM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. opengl DC question
    By SAMSAM in forum Game Programming
    Replies: 6
    Last Post: 02-26-2003, 08:22 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21