tags:

views:

105

answers:

4

I have a program that I need to read in an array of strings from a file. The array must be C type strings (char * or char[]).

Using the following code, I get a bad access error:

for (i = 0; i < MAX_WORDS && !inputFile.eof(); i++) {
    inputFile >> words[i];
}

words is declared as:

char *words[MAX_WORDS];
+2  A: 

iostreams don't allocate memory automatically for you, you have to allocate beforehand. You currently have just an array of pointers containing garbage-values.

Note however that you don't control the length of the input here. Temporarily storing into a C++ string and allocating suitably sized C-strings then would be preferrable.

Alternatively you could limit the input length using the setw() manipulator:

inputFile >> std::setw(allocatedWordLength-1) >> words[i];
Georg Fritzsche
I am not allowed to use C++ strings at all in my program (as per my militant teacher's wishes).setw doesn't seem to work for me. I read somewhere that it was defined in iomanip but I get errors when I try to use it.
David Beck
@David: Did you `#include <iomanip>`? You could add the errors as an update to the question or open a new one about the iomanip problems.
Georg Fritzsche
@The teacher - Why not? (Don't worry, it's a rhetorical question.)
jmucchiello
A: 

Is each string in the array a line in the file? Are you using std::ifstream? If not do so and then use std::getline. getline reads into std::string but c_str() gives you, well, a c_str to use directly or copy into into your array

Patrick
+1  A: 

Your declaration

char *words[MAX_WORDS];

only allocates an array of pointers, not memory for the buffers. Those pointers aren't pointing at allocated memory, so when you write to those addresses, you get an access error.

You need to allocate an array of buffers. One way is to declare a two-dimensional array:

char words[MAX_WORDS][MAX_WORD_LENGTH];

assuming MAX_WORD_LENGTH is set to however long your words can possibly be plus one for the null terminator. Then your loop should work.

JohnMcG
+1  A: 

JohnMcG gave an excellent answer to your immediate problem, but there's other things to be concerned about that won't fit into a comment. Remember that a character array can hold a string one char smaller than its length, so use MAX_WORD_LENGTH + 1 for the length. I'd also suggest initializing those strings to the null string, so that there's a '\0' at the beginning of each string before the loop.

Is there any reliable length limit on the words? If not, the problem becomes more involved with C-style strings (although not C++ strings). You'll have to allocate pointers (as you have), and reallocate them as necessary while reading character by character. Fiddly stuff, and this is one case where I'd recommend using malloc()/free()/realloc() rather than C++ memory management.

I assume you're already aware that you're reading words and not lines. Your array name suggests that, but it's a common error among students.

You didn't declare i in the for statement, so it's a variable with scope outside, which brings up the possibility that you might be using its value later. If so, remember that .eof() doesn't mean the program has run out of input, it means the program has tried to read off the end of the file. If the file ends in a whitespace character (like '\n'), it will read the last word and then increment i and read nothing. If it doesn't, it will try to read past the end of file while reading the last word, and won't increment i again.

If you need a count of words, then, you need to have initialized the memory, as mentioned above, and you need to check whether words[i] is empty or not (strlen() is overkill, check the first character for \0).

David Thornley