473,396 Members | 1,927 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How to load a text file into a char **?

Is there a safe (unlikely to cause overflows or segfaults) way to load
a text file into a char ** array? I thought of using getline, but it
needs a fixed-length string, and I don't know how many lines or
characters per line the file has.
Jul 18 '08 #1
8 3234
On Jul 18, 11:53*am, ampheta...@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults) way to load
a text file into a char ** array? I thought of using getline, but it
needs a fixed-length string, and I don't know how many lines or
characters per line the file has.
You have wrong information: getline needs a string, not a fixed-length
one, and string is never fixed-length anyway.

After you read it in to the string, then you can make a copy of the
contents with the c_str() member function.

Ali
Jul 18 '08 #2
On Jul 18, 3:29*pm, acehr...@gmail.com wrote:
On Jul 18, 11:53*am, ampheta...@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults) way to load
a text file into a char ** array? I thought of using getline, but it
needs a fixed-length string, and I don't know how many lines or
characters per line the file has.

You have wrong information: getline needs a string, not a fixed-length
one, and string is never fixed-length anyway.

After you read it in to the string, then you can make a copy of the
contents with the c_str() member function.

Ali
I was talking about fstream::getline. I think it takes a char * and a
size argument.

But how would I go about allocating the first part of the array (the
number of lines)?
Jul 18 '08 #3
am********@gmail.com wrote:
On Jul 18, 3:29 pm, acehr...@gmail.com wrote:
>On Jul 18, 11:53 am, ampheta...@gmail.com wrote:
>>Is there a safe (unlikely to cause overflows or segfaults) way to load
a text file into a char ** array? I thought of using getline, but it
needs a fixed-length string, and I don't know how many lines or
characters per line the file has.
You have wrong information: getline needs a string, not a fixed-length
one, and string is never fixed-length anyway.

After you read it in to the string, then you can make a copy of the
contents with the c_str() member function.

Ali

I was talking about fstream::getline. I think it takes a char * and a
size argument.

But how would I go about allocating the first part of the array (the
number of lines)?
That would mean you need to read them all out to count them. As I
recall, text editors don't have an array of lines, they keep a linked
list. Perhaps that's what you should consider...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 18 '08 #4
On Jul 18, 10:05 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
ampheta...@gmail.com wrote:
On Jul 18, 3:29 pm, acehr...@gmail.com wrote:
On Jul 18, 11:53 am, ampheta...@gmail.com wrote:
>Is there a safe (unlikely to cause overflows or segfaults)
way to load a text file into a char ** array? I thought of
using getline, but it needs a fixed-length string, and I
don't know how many lines or characters per line the file
has.
You have wrong information: getline needs a string, not a
fixed-length one, and string is never fixed-length anyway.
After you read it in to the string, then you can make a
copy of the contents with the c_str() member function.
I was talking about fstream::getline. I think it takes a
char * and a size argument.
But how would I go about allocating the first part of the
array (the number of lines)?
That would mean you need to read them all out to count them.
Not really. He could always reimplement the logic of
std::vector.
As I recall, text editors don't have an array of lines, they
keep a linked list. Perhaps that's what you should
consider...
I don't think that there's any absolute rule as to how text
editors work. Many, I believe, keep all of the text in a
single, large buffer, and not stored as lines, often keeping the
text before the cursor at the front, the text after the cursor
at the end, and the empty space in the array at the cursor
position.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 18 '08 #5
am********@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults) way to load
a text file into a char ** array?
A char** array? Are you sure you got that right?
I thought of using getline, but it
needs a fixed-length string, and I don't know how many lines or
characters per line the file has.
// puts the entire contents in a char array
vector<charread( const char* fileName )
{
vector<charresult;
ifstream file( fileName, ios::binary );
char ch;
while ( file.get( ch ) )
result.push_back( ch );
return result;
}

or

// puts the entire contents in a char* array,
// breaks file by newlines.
vector< vector<char read( const char* fileName )
{
vector< vector<char result;
ifstream file( fileName );
string str;
while ( getline( file, str ) ) {
result.push_back( vector<char>( str.begin(), str.end() ) );
result.back().push_back( 0 ); // null terminate each line?
}
return result;
}

I guess for a char** array, you could put each word in a separate
block...
Jul 19 '08 #6
On Jul 19, 3:57 am, "Daniel T." <danie...@earthlink.netwrote:
ampheta...@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults)
way to load a text file into a char ** array?
A char** array? Are you sure you got that right?
Maybe he needs to interface with some legacy C code.
(Otherwise, of course, std::vector< std::string is the obvious
choice.)
I thought of using getline, but it needs a fixed-length
string, and I don't know how many lines or characters per
line the file has.
// puts the entire contents in a char array
vector<charread( const char* fileName )
{
vector<charresult;
ifstream file( fileName, ios::binary );
char ch;
while ( file.get( ch ) )
result.push_back( ch );
return result;
}
or
// puts the entire contents in a char* array,
// breaks file by newlines.
vector< vector<char read( const char* fileName )
{
vector< vector<char result;
ifstream file( fileName );
string str;
while ( getline( file, str ) ) {
result.push_back( vector<char>( str.begin(), str.end() ) );
result.back().push_back( 0 ); // null terminate each line?
}
return result;
}
I guess for a char** array, you could put each word in a separate
block...
I think he wants one string per line. But I'd still use a
vector of string for the reading, only converting into char**
once the file had been read, e.g.:

std::vector< std::string tmp ;
std::string line ;
while ( std::getline( file, line ) ) {
tmp.push_back( line ) ;
}
std::vector< char const* result ;
for ( std::vector< std::string >::const_iterator
iter = tmp.begin() ;
iter != tmp.end() ;
++ iter ) {
result.push_back( iter->c_str() ) ;
}
result.push_back( NULL ) ; // if needed.
// use &result[0].

(In fact, I just did exactly this yesterday, to interface with
openldap.)

Note that in this case, you cannot simply return &result[0], and
expect it to work. For obvious reasons, you must use &result[0]
before either tmp or result go out of scope. In a larger
application, the solution, I think would be to create a class
which contained these two members, contructed the above in its
constructor, and had a function to return the char**. (It the
needed type really is char**, as was the case with openldap,
you'll have to const_cast.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 19 '08 #7
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
ampheta...@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults)
way to load a text file into a char ** array?
A char** array? Are you sure you got that right?

Maybe he needs to interface with some legacy C code.
(Otherwise, of course, std::vector< std::string is the obvious
choice.)
A vector<stringwould equate to a char* array, not a char** array.

char[] char_array = "hello world";
char*[] char_ptr_array = { "a", "b", "c" };
char**[] char_ptr_ptr_array = ?

Maybe the OP just messed up a bit in his terminology?
I thought of using getline, but it needs a fixed-length
string, and I don't know how many lines or characters per
line the file has.
The below is the same as what I had before, except the last step of
turning the vector<vector<char into a char** is added.

template < typename T >
struct PtrToFirst : unary_function< vector< T >, T* {
T* operator()( vector< char >& vec ) const {
return &vec[0];
}
};

typedef vector< vector< char temp_type;
temp_type tmp;
string str;
while ( getline( file, str ) ) {
tmp.push_back( vector<char>( str.begin(), str.end() ) );
tmp.back().push_back( 0 ); // null terminate each line?
}
vector< char* result;
transform( tmp.begin(), tmp.end(), back_inserter( result ),
PtrToFirst<char>() );
// or the above line could be done with:
//for ( temp_type::iterator it = tmp.begin(); it != tmp.end(); ++it )
// result.push_back( &it->at( 0 ) );
result.push_back( 0 );

char** wow = &vector[0]
I think he wants one string per line. But I'd still use a
vector of string for the reading, only converting into char**
once the file had been read, e.g.:

std::vector< std::string tmp ;
std::string line ;
while ( std::getline( file, line ) ) {
tmp.push_back( line ) ;
}
std::vector< char const* result ;
for ( std::vector< std::string >::const_iterator
iter = tmp.begin() ;
iter != tmp.end() ;
++ iter ) {
result.push_back( iter->c_str() ) ;
}
result.push_back( NULL ) ; // if needed.
// use &result[0].

(In fact, I just did exactly this yesterday, to interface with
openldap.)

Note that in this case, you cannot simply return &result[0], and
expect it to work. For obvious reasons, you must use &result[0]
before either tmp or result go out of scope. In a larger
application, the solution, I think would be to create a class
which contained these two members, contructed the above in its
constructor, and had a function to return the char**. (It the
needed type really is char**, as was the case with openldap,
you'll have to const_cast.)
I agree, but I say avoid the (multiple) const_casts by using a vector<
vector< char instead of a vector< string >.

Note that our solutions are remarkably similar. The only difference is
that I don't have to go through the extra step to remove the const.
Jul 19 '08 #8
On Jul 19, 2:43 pm, "Daniel T." <danie...@earthlink.netwrote:
James Kanze <james.ka...@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
ampheta...@gmail.com wrote:
Is there a safe (unlikely to cause overflows or segfaults)
way to load a text file into a char ** array?
A char** array? Are you sure you got that right?
Maybe he needs to interface with some legacy C code.
(Otherwise, of course, std::vector< std::string is the obvious
choice.)
A vector<stringwould equate to a char* array, not a char** array.
You're right. I was thinking of the more usual case, and just
read it as a typo: an array that you "access" through a char**.
char[] char_array = "hello world";
char*[] char_ptr_array = { "a", "b", "c" };
char**[] char_ptr_ptr_array = ?
Maybe the OP just messed up a bit in his terminology?
Probably. Although there's an outside chance that he wanted an
array of lines, each line being an array of words, I suspect
that that's not really the case.
I thought of using getline, but it needs a fixed-length
string, and I don't know how many lines or characters per
line the file has.
The below is the same as what I had before, except the last
step of turning the vector<vector<char into a char** is
added.
Yes. I was basing my posting on yours, since you seemed to be
the only one posting with the correct approach.
Note that in this case, you cannot simply return &result[0],
and expect it to work. For obvious reasons, you must use
&result[0] before either tmp or result go out of scope. In
a larger application, the solution, I think would be to
create a class which contained these two members, contructed
the above in its constructor, and had a function to return
the char**. (It the needed type really is char**, as was
the case with openldap, you'll have to const_cast.)
I agree, but I say avoid the (multiple) const_casts by using a vector<
vector< char instead of a vector< string >.
That's a possibility. I think it depends. If the data really
is supposed to be immutable, and it's just the legacy interface
which doesn't use const, I prefer the const_cast, since it says
what I mean.

In my case (which by coincidence, showed up two days ago), I was
dealing with data from the client; pushing an std::vector<char>
out to the interface level, when I was logically dealing in
strings, didn't seem appropriate (although I find I often use
vectors of char, instead of strings, at the implementation
level).
Note that our solutions are remarkably similar. The only
difference is that I don't have to go through the extra step
to remove the const.
Great minds think alike:-). I wasn't criticizing your
suggestions, just completing them. I did think it important to
point out that even if the char** was imposed by some sort of
legacy interface, some sort of std::vector was still the
preferred option. I may prefer vector< string and the
const_cast, while you prefer vector< vector< char , but the
difference is peanuts, compared to the difference between one of
those and char** or char *[].

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 20 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: hall | last post by:
I have a problem with my design of a templatized class. I'm trying to figure out how to load and save the data inside it, but can't. My class looks like this ------------------------------------...
1
by: wtnt | last post by:
Hello. I've searched all over and haven't seen another thread with this problem. Please bear with me as I try to explain. thanks. :) I have some programs that need to be cross-platform...
6
by: JS | last post by:
EE instance DB2 v7.2.0 fixpack 3 on WIN2K. I select some data from a table A and write it to a file using the COALESCE function and whitespace as the null character: eg coalesce(col1, ' '). This...
2
by: Michael Blair | last post by:
I would like to edit an incoming date field which is mm/dd/yyyy and convert it to yyyy-mm-dd as required by mysql. Any ideas?
6
by: stefaan.lhermitte | last post by:
Dear mysql-ians, I am using mysql 5.0 and I want to load a huge txt-file in my database. My text file (file.txt) looks like: col1 col2 col3 ... col200 col1 col2 col3 ... col200 .... col1...
4
by: andrewcw | last post by:
I am moving some code forward from .NET 1.1. I was able to load the XSL file and perform the transform. The MSDN documentation looks like it should be easy. But I get a compile error. Ideas ?...
19
by: natG | last post by:
On a warehouse app, our Java clients constantly load/insert rows into the db. I would like to throttle these inserts (1.5 million rows per hr) from the Java app, based on current 'busy state' of...
9
by: anachronic_individual | last post by:
Hi all, Is there a standard library function to insert an array of characters at a particular point in a text stream without overwriting the existing content, such that the following data in...
13
by: rdudejr | last post by:
Hi all, I hardly ever make a post unless I am having a very purplexing issue, so this one should be good... I am trying to do a load against a database on an AIX server into a DB2 v9.1...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.