File handling in C++

J

John Ruiz

Hello everyone. I find it amazing how in C++ that reading in files still
more or less requries usage of char * type. I know there's getline to use
std::string, but the basic_stream::get methods don't work with std::string.
I would like to create a function perhaps something like:

void read(std::string &s, int numBytes);

where the user passes in s to have numBytes of data read from a file into s.
Well, this would require me to do a thing like allocate memory of char bytes
and then do a copy over to the string. So, for this reason, I find myself
sticking to doing the C thing and using FILE pointers and all because to me,
it seems like a waste to read into a char array, then copy over to
std::string, so to avoid that copy, I just do the C thing.

So, am I unaware of a way around this problem? Thanks in advance.

John
 
J

Jeff Schwab

John said:
Hello everyone. I find it amazing how in C++ that reading in files still
more or less requries usage of char * type. I know there's getline to use
std::string, but the basic_stream::get methods don't work with std::string.
I would like to create a function perhaps something like:

void read(std::string &s, int numBytes);

where the user passes in s to have numBytes of data read from a file into s.
Well, this would require me to do a thing like allocate memory of char bytes
and then do a copy over to the string.

How else would such a function work, even if it were part of the
standard library? Even with a bit of memcpy magic, how would you get
around copying the text out of the I/O system's buffer? Would it be
more efficient to use unbuffered input?
So, for this reason, I find myself
sticking to doing the C thing and using FILE pointers and all because to me,

What does that accomplish? Aren't you still working with C-style
strings? What problem have you solved or avoided?
it seems like a waste to read into a char array, then copy over to
std::string, so to avoid that copy, I just do the C thing.

You didn't have to do that copy when you were using std::istream,
either. You just chose to do so because you liked std::string. How has
that changed? Does mixing the standard library with the core language
make you feel bad?
So, am I unaware of a way around this problem? Thanks in advance.

Why not write your own implementation of "read" to use std::string if
you don't like null-terminated character arrays? You could append one
character at a time, as needed. If you're willing to spare a bit of
space, you could buffer the input yourself to get more characters with
each call to std::istream::read. The buffer even could be automatic, so
it wouldn't take up space unless your custom "read" function actually
were used. Wait a minute, let me go try something.

Ok, here you go. This isn't production code, it's just something I
whipped up; so, don't berate me if you see something you like. Do feel
free to point it out, though.

#include <cstddef>
#include <istream>
#include <string>

namespace IO
{
typedef std::istream Istream;
typedef std::string String;
typedef std::size_t Size;


/* Read as many chars as possible (up to given maximum) from an
* input stream and append them to a string. Return the number of
* characters successfully read.
*/
Size read( Istream&, String&, Size maximum_quantity_of_chars_to_read );
}

#include <iostream>

int main( )
{
std::string s;

IO::read( std::cin, s, 10 );

std::cout << s << '\n';
}

namespace IO
{
Size const buffer_size = 1024;

typedef char Buffer[ buffer_size ];
}

IO::Size IO::read( Istream& input, String& s, Size max_chars )
{
Size num_chars_read = 0; // To be returned.
Buffer buffer;

for( Size full_buffers_to_read = max_chars / buffer_size;
input and full_buffers_to_read;
--full_buffers_to_read )
{
input.read( buffer, buffer_size );
s.append( buffer, input.gcount( ) );
num_chars_read += input.gcount( );
}

Size chars_still_wanted = max_chars % buffer_size;

if( input and chars_still_wanted )
{
input.read( buffer, chars_still_wanted );
s.append( buffer, input.gcount( ) );
num_chars_read += input.gcount( );
}

return num_chars_read;
}
 
J

Jeff Schwab

Jeff said:
This isn't production code, it's just something I
whipped up; so, don't berate me if you see something you
don't

like. Do feel free to point it out, though.
 
J

John Harrison

John Ruiz said:
Hello everyone. I find it amazing how in C++ that reading in files still
more or less requries usage of char * type. I know there's getline to use
std::string, but the basic_stream::get methods don't work with std::string.
I would like to create a function perhaps something like:

void read(std::string &s, int numBytes);

where the user passes in s to have numBytes of data read from a file into s.
Well, this would require me to do a thing like allocate memory of char bytes
and then do a copy over to the string. So, for this reason, I find myself
sticking to doing the C thing and using FILE pointers and all because to me,
it seems like a waste to read into a char array, then copy over to
std::string, so to avoid that copy, I just do the C thing.

Thaink about what you are saying here. You are preferring ugly code just
because of a percieved inefficiency in copying some bytes (have you ever
timed it to see how many extra fractions of a millisecond it takes). Write
your read function and forget about 'inefficiency'. The single biggest
inefficiency in the whole computing industry is poor quality code.
So, am I unaware of a way around this problem? Thanks in advance.


John

john
 
J

John Ruiz

John Harrison said:
into

Thaink about what you are saying here. You are preferring ugly code just
because of a percieved inefficiency in copying some bytes (have you ever
timed it to see how many extra fractions of a millisecond it takes). Write
your read function and forget about 'inefficiency'. The single biggest
inefficiency in the whole computing industry is poor quality code.


You could read into a vector<char>. It's pretty rare to want to read a fixed
number of bytes of *text*, so maybe you shouldn't be using string at all.


john

Hi guys. Thanks for the input and of course, I'm not going to berate your
code. This is only a forum. Later, and I'll be posting more questions I'm
sure later on.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top