Is it possible to use std :: string for read ()?

Is it possible to use std :: string for read ()?

Example:

std::string data; read(fd, data, 42); 

Normal, we should use char *, but is it possible to use std :: string directly? (I prefer not to create char * to save the result)

Thanks x

+4
source share
6 answers

Well, you need to somehow create a char* , as this function requires. (By the way: you are talking about the Posix read function, not you, not std::istream::read ?) The problem is not char* , this is what char* indicates (which I suspect that you are actually business meant).

The simplest and most common solution here is to use a local array:

 char buffer[43]; int len = read(fd, buffer, 42); if ( len < 0 ) { // read error... } else if ( len == 0 ) { // eof... } else { std::string data(buffer, len); } 

If you want to write directly to std::string , however, this is possible (although not necessarily a good idea):

 std::string data; data.resize( 42 ); int len = read( fd, &data[0], data.size() ); // error handling as above... data.resize( len ); // If no error... 

This avoids copying, but, frankly ... The copy is small compared to the time it takes to actually read and to allocate memory in a row. It also has a (possibly negligible) flaw in the resulting string, which has an actual buffer of 42 bytes (rounded to any), and not just the minimum required for the characters actually read.

(And since people sometimes raise the issue of memory contact in std:;string : this was a problem ten or more years ago. The original specifications for std::string were designed to allow non-contiguous implementations, according to the then-popular class rope . In practice, no developer found this to be useful, and people started to get in touch. At this point, the standardization committee decided to harmonize the standard with existing practices and require contact. So ... no implementation would ever be and adjacent and no future implementation would not contradict adjacency requirements given in C ++ 11.)

+7
source

If char * is required for the read function, then no. You can use the address of the first element of std :: vector char if it was first changed. I don’t think that old (pre C ++ 11) lines guarantee continuous memory, otherwise you could do something like a line.

0
source

No, you cannot and should not. Typically, std :: string implementations internally store other information, such as the size of the allocated memory and the length of the actual string. The C ++ documentation explicitly states that changing the values ​​returned by c_str() or data() leads to undefined behavior.

0
source

No, but

 std::string data; cin >> data; 

works just fine. If you really want read(2) behavior, then you need to allocate and manage your own character buffer.

0
source

Since read () is for inputting raw data, std :: string is actually a bad choice because std :: string processes the text. std :: vector seems to be the right choice for processing raw data.

0
source

Using std :: getline from a string library - see cplusplus.com - can read from a stream and write directly to a string object. Example (again plucked from cplusplus.com - 1st hit on google for getline):

 int main () { string str; cout << "Please enter full name: "; getline (cin,str); cout << "Thank you, " << str << ".\n"; } 

This will work when reading from stdin (cin) and from a file (ifstream).

-1
source

All Articles