It used to work: Reading from std::cin
to a dynamically allocated char
array - or to an array passed in as a parameter (see MCVE below).
#include <iostream>
void read (char str[256]) //or omit the # between the []'s -- no difference
{
std::cin >> str; //error
}
int main ()
{
char s1 [256];
char* s2 = new char[256];
char s3 [256];
std::cin >> s1; //OK
std::cin >> s2; //error
read (s3);
return 0;
}
I believe the problem is a C++20 update called Fixing operator>>(basic_istream&, CharT*)
. Its purpose is to prevent std::cin
from overflowing the string it's reading into, and cppreference.com does list new prototypes for std::istream
's operator>>
that now have CharT (&s)[N]
, not CharT* s
, as the argument taken.
Confirmation: this MCVE works with g++ 10 (which doesn't support this), and with Visual Studio using Default as the language flag; but using /std:c++latest
, VS complains:
binary '>>': no operator found which takes a right-hand operand of type 'char *' (or there is no acceptable conversion)
So I totally get what the compiler's complaining about. But how do I use std::cin
with arrays passed in as parameters, or dynamic arrays?
(Also: how does C++ know, when it's ready to read, whether an array was created dynamically or statically? It's not supposed to be able to draw that distinction after declaration!)
But how do I use cin with arrays passed in as parameters, or dynamic arrays?
Don't. If you have a char array, give it the char array like
void read (char (&str)[256]) // now we have a reference to an array, so we know its size
{
std::cin >> str;
}
// or if we don't care about the size, we just want an array
template <std::size_t N>
void read (char (&str)[N]) // now we have a reference to an array, so we know its size
{
std::cin >> str;
}
and if you have a dynamic size, use a std::string
which still works with cin
void read (std::string& str)
{
std::cin >> str;
}
(Also: how does C++ know, when it's ready to read, whether an array was created dynamically or statically? It's not supposed to be able to draw that distinction after declaration!)
It's not that it knows that its ready to read, it that it knows the size that it can read. When you give it a pointer, it just has to trust the pointer points to enough memory. If you give it an array, by passing the array by reference, then the compiler knows the size it can read as the size of an array is part of the type information, unlike a pointer. Don't confuse array's decaying into a pointer into arrays being a pointer. They are two different things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With