0

So I'm attempting to create a Befunge interperter and reading a text file into an array. I'm using this code:

char map[100][100]; //not 85 x 20
//load the source
ifstream f;
f.open("file.txt", ios::in);
string s;
int i = 0;
while(f.good() && i < 100)
{
    getline(f, s);
    map[i] = s.c_str();
    i++;
}

This doesn't work, does anyone know a way to do it without manually looping through the string?

4
  • 2
    But do you understand why it doesn't work? That's rather important... Commented Feb 10, 2012 at 23:09
  • 2
    Use strcpy and watch out for buffer overflow. You cannot assign to an array. Or even better, use std::vector<std::string> rather than yacky C strings Commented Feb 10, 2012 at 23:10
  • Any reason you can't use std::vector<std::string> or even std::string[100]? If you're using C++, take advantage of its types! Commented Feb 10, 2012 at 23:14
  • A vector is probably the best idea since I'm planning for unbounded storage, and yes @ildjarn I know why it doesn't work. Commented Feb 10, 2012 at 23:16

3 Answers 3

3

Use strncpy() and specify the number of bytes:

strncpy(map[i], s.c_str(), 100);
map[i][99] = '\0'; /* this could trim s.c_str(), but at least you don't get an overflow */

instead of:

map[i] = s.c_str();

By specifying the number of bytes copied as, at most, 100, you ensure that you don't overflow map[i]. The strncpy() function will pad map[i] with terminators, if strlen(s.c_str()) < 100. In the case where strlen(s.c_str()) >= 100, the string will be truncated in order to provide map[i] with the requisite null terminator.

Sign up to request clarification or add additional context in comments.

2 Comments

This would work but I'm going to use a std::vector<std::string> since I need no limits on storage. Thanks anyway though.
Using a vector of string would definitely be the most idiomatic C++ approach, and you wouldn't have to deal with line length issues (at least up to system memory, more or less).
0

I think it is safer to do so

char* map[100];
....   

while(f.good() && i < 100)
{
    getline(f, s);
    map[i] = new char[s.length() + 1];
    strcpy (map[i], s.c_str());
    i++;
}

2 Comments

To be really safe, you might want to test the result of map[i] = ... to ensure that you actually have that space available, before the strcpy().
I said "safer", not "the safest" )))) I gave an idea and direction for thought, not a ready piece of code
-1

Contrary to the other answers already posted in here, you should NOT be attempting to use strcpy to copy into "map". Before you do any copying, you want to ensure that you do not overrun the buffer. To do this, you should not use the size of the source, but instead the size of the destination. The reason for this is that the source could potentially be longer than the destination has room. In order to avoid an issue that might not rear its head until you've done some other intensive computations you should ensure that you don't attempt to copy into a destination that isn't large enough to contain what you are trying to copy into it.

This is the function signature for copying strings (well, the one you should be using here):

strncpy(dest, source, size);

Here's what you should use instead:

strncpy(map[i], s.c_str(), sizeof(map[i]));

Edit:

Alternatively you could use strncpy_s() (if you are on Windows!), which allows you to specify both source and destination lengths.

strncpy_s(dest, dest_size, source, source_size)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.