OK. I tried this myself and found several problems with the code in my previous post.
Had to wrap my head around exactly what's going on with the '\0' characters.
It's been a while.
We have to be careful about over writing it because it marks end of string.
Your PROBLEM 1 results from trying to copy a string lacking a '\0' character (so it goes forever).
I think PROBLEM 2 results from the mess created by PROBLEM 1, and being 1 char short in allocation.
Also, it's OK to strcat to an empty string (so long as buff[0] == '\0'), so the check isn't needed.
I have the code working.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
int main()
{
ifstream infile;
infile.open("Stories.txt");//open the text file
if (!infile)
{
cout << "Unable to open file";
return 1; // terminate with error
}
unsigned int MaxNoStories = 40;// doesn't need to be constant. This would be one ctor argument
char **myStories = new char *[MaxNoStories];
unsigned int StoryNo = 0;
char line[1000] = {0};// for each line to read into
char buff[1000] = {0};// local array large enough to contain all lines before the line "%%%%%"
unsigned int length = 0;
while(!infile.eof() && StoryNo < MaxNoStories)// watch for end of array too!
// while( infile.getline( line, 500) )
{
infile.getline( line, 500);
if( strcmp(line, "%%%%%") !=0 )
{
length = strlen(line);
line[length] = '\n';// over write the '\0' with '\n'
line[length+1] = '\0';// put '\0' at the end so strcat will work
strcat( buff, line );// OK to strcat to an empty buff. No need to strcpy 1st time
}
else
{
length = strlen(buff);
myStories[StoryNo]= new char [length + 1];// +1 for the '\0'
strcpy(myStories[StoryNo], buff);
StoryNo++;
buff[0] = '\0';// reset for the next story. Makes buff appear empty
}
}// end while
for( unsigned i = 0; i < StoryNo; ++i )
cout << myStories[i] << "\n\n";
return 0;
}
| |
I puzzled why the 1st line starts with a space for a while before I finally saw this line:
strcpy(buff," ");
It isn't needed.
I decided to post my complete code because there are several local variables and some code removed.
I also changed a few variables from type int to unsigned int, to get rid of those pesky "comparison of signed to unsigned" warnings.
Shouldn't myStories[StoryNo] as a double pointer (char **myStories = new char *[MaxNoStories];) be defined in the while loop as *myStories[StoryNo] = new char *[length+1]; since myStories is a dynamic double pointer????
|
No. The use of [] does 2 things. It advances the pointer
and dereferences it.
You would have to use the * this way:
*(myStories + StoryNo) = new char[length+1];// not char*