Home > Net >  Input from an istream to a char* pointer?
Input from an istream to a char* pointer?

Time:07-13

I am reading Bjarne Stroustrup's "Programming Principles and Practice Using C " (second edition). On page 660-661, the writers define a function as follows:

istream& read_word(istream& is, char* buffer, int max)
    // read at most max-1 characters from is into buffer
{
    is.width(max);    // read at most max-1 characters in the next >>
    is >> buffer;     // read whitespace-terminated word,
                      // add zero after the last character read into buffer
    return is;
}

Later in int main(), the function is called as read_word(cin,s,max); where cin is std::cin, max is an int, and s is a char array of size max.

I don't understand how is >> buffer; works. In particular, that line gives an error when I tried to run the code:

C2679 binary '>>': no operator found which takes a right-hand operand of type 'char *' (or there is no acceptable conversion)

There is no user-defined operator>> or further explanation on that line (except the comment) in the book.

I wonder if we can use things like is >> buffer; in any meaningful way? If so, how does it work? Or is this an error in the book?


Update: I'm using Visual Studio 2022. I found that the code runs successfully with C 14/17, but not with C 20. The results are similar for clang and gcc.

CodePudding user response:

The std::basic_istream::operator >> overload that takes a char* argument (overload #2 in this cppreference page) was removed in C 20. This change will, no doubt, break huge amounts of existing code, including examples given by Bjarne Stroustrup himself!

The C 20 replacement, taking a char (&s)[N] argument instead, seems (to me, at least) far less accessible. One way to adapt to this change is to rewrite the read_word function as a template, when you would no longer require the explicit max argument and the call to is.width():

template <size_t N>
std::istream& read_word(std::istream& is, char (&buffer)[N])
{
    is >> buffer;
    return is;
}

However, as mentioned in Alan Birtles' answer, you should really be moving away from raw char[] arrays and start using std::string, instead.

CodePudding user response:

The stream operator taking a raw char pointer has been replaced with one taking a fixed sized char array in c 20. The simplest solution is to use std::string instead.

To use an array your code would be something like:

template <size_t N>
istream& read_word(istream& is, char (&buffer)[N], int max)
    // read at most max-1 characters from is into buffer
{
    is.width(max);    // read at most max-1 characters in the next >>
    is >> buffer;     // read whitespace-terminated word,
                      // add zero after the last character read into buffer
    return is;
}

Note that this will now read at most N-1 characters, if N and max are the same then you can omit max and the width call.

  • Related