Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input from an istream to a char* pointer?

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.

like image 228
CPPL Avatar asked Dec 29 '25 12:12

CPPL


1 Answers

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.

like image 94
Adrian Mole Avatar answered Dec 31 '25 02:12

Adrian Mole