GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 26-Jan-2005, 21:11
swayp swayp is offline
New Member
 
Join Date: Jan 2005
Posts: 25
swayp is on a distinguished road

More Reading in problems


Ok I'm having problems reading in a file again. Its the same CD Database but I decided to add a track listing to it. So, since different cds have different numbers of tracks, I added a loop in there to read in the tracks until it reads in a string that I compare to break it out of the loop. However, everything seems to be working fine except I get a segmenation fault. I tried messing around with cout's and found that everything works fine but it wont print my last cout once its supposed to break out of the loop once it reaches the end of the file, meaning it most not be reaching the end of the file.

I don't get it... Here is the code:

CPP / C++ / C Code:
int main()
{
  ifstream infile;
  char* line = new char[512];
  char* temp = new char[100];
  char* garbage = new char[50];
  char* artist = new char[50];
  char* title = new char[50];
  char* year = new char[50];
  char* song1 = new char[50];
  char test[7] = "------";

  infile.open("databaseFile.txt");

  while ( infile.peek() != EOF )
    {
      infile.getline(garbage,100);

      infile.getline(line,512);

      temp = strtok(line, " ");
      strcpy(garbage,temp);

      temp = strtok(NULL, "\n");
      strcpy(artist, temp);

      cout << "Artist: " << artist << endl;

      infile.getline(line,512);

      temp = strtok(line, " ");
      strcpy(garbage,temp);

      temp = strtok(NULL, "\n");
      strcpy(title,temp);

      cout << "Title: " << title << endl;

      infile.getline(line,512);

      temp = strtok(line, " ");
      strcpy(garbage,temp);

      temp = strtok(NULL, "\n");
      strcpy(year,temp);

      cout << "Year: " << year << endl;

      infile.getline(line,512);

      //reading in Track Lising:
      temp = strtok(line, "\n");      strcpy(garbage,temp);


      do
        {
          infile.getline(line,512);

          temp = strtok(line, "\n");
          strcpy(song1,temp);

          cout << "Printing out song: ";
          cout << song1 << endl;

        } while ( strcmp (song1,test) != 0 );

      //read in blank line
      infile.getline(garbage,100);  

    }

  cout << "After breaking out of reading file loop" << endl;

}

This is the databaseFile.txt:
Code:
--CD-- Artist: Outkast Title: ATLiens Year: 1996 Track Listing: 1. You May Die (Intro) 2. Two Dope Boys (In a Caddilac) 3. ATLiens 4. Wheelz of Steel 5. Jazzy Belle 6. Elevators (Me & You) 7. Ova Da Wudz 8. Babylon 9. Wailin' 10. Mainstream 11. Decatur Psalm 12. Millenium 13. E.T. (Extraterrestrial) 14. 13th Floor/Growing Old 15. Elevators (ONP 86 Mix) ------ --CD-- Artist: Outkast Title: Aquemini Year: 1998 Track Listing: 1. Hold On Be Strong 2. Return of the 'G' 3. Rosa Parks 4. Skew it on the Bar-B 5. Aquemini 6. Synthesizer 7. Slump 8. West Savannah 9. Da' Art of Storytellin (Part 1) 10. Da' Art of Storytellin (Part 2) 11. Mamacita 12. SpottieOttieDopalicious 13. Y'All Scared 14. Nathaniel 15. Liberation 16. Chonkyfire ------


It wont print the last cout that says After breaking out of reading file.

Anyone got any ideas?
Last edited by dsmith : 27-Jan-2005 at 06:45. Reason: Please use [c] & [/c] when posting C code
  #2  
Old 27-Jan-2005, 07:45
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by swayp
I added a loop in there to read in the tracks until it reads in a string that I compare to break it out of the loop. However, everything seems to be working fine except I get a segmenation fault. I tried messing around with cout's and found that everything works fine but it wont print my last cout once its supposed to break out of the loop once it reaches the end of the file, meaning it most not be reaching the end of the file.



It wont print the last cout that says After breaking out of reading file.

Anyone got any ideas?

The art of debugging depends on the ability to use the information that you are given so that you can get to the next step:

If it bombs before you print the "after breaking out" message after breaking out of the do{} loop, then it isn't breaking out of the do {}loop.

Check for end of file after the getline statement (sometimes your program is not reading what you think it is). (It's just logic, you know.) Also, I added a few more couts to see in greater detail what's happening.

Try the following.

If it keeps your program from bombing, then you might do this:

Comment out the "if(infile.eof()){}" block and see if the cout statements help you see what's going on.

CPP / C++ / C Code:
      do
        {
          infile.getline(line,512);
          if (infile.eof()) {
            cout << endl << "EOF encountered in do{} loop" << endl << endl;
            break;
          }
          cout << "96. line: <" << line << ">" << endl;

          temp = strtok(line, "\n");
          cout << "97. temp = <" << (void *)temp<< ">";
          strcpy(song1,temp);
          cout << "98. song1 = <" << song1 << ">" <<endl;

          cout << "99. Printing out song: <" << ">, test = <" << test << ">" << endl;
          cout << song1 << endl;

        } while ( strcmp (song1,test) != 0 );


Regards,

Dave
Last edited by davekw7x : 27-Jan-2005 at 09:06.
  #3  
Old 27-Jan-2005, 11:50
swayp swayp is offline
New Member
 
Join Date: Jan 2005
Posts: 25
swayp is on a distinguished road
Ok, I tried out your idea just now. I think I may have to play around with the loop a little more because it might be running one more time than I want it to, but it shouldnt be causing the seg fault.

CPP / C++ / C Code:
      do
        {
          infile.getline(line,512);

          if (infile.eof())
            {
              cout << endl << "EOF encountered in Do loop" << endl;
              break;
            }
          cout << "96. line: <" << line << ">" << endl;

          temp = strtok(line, "\n");
          cout << "97. temp = <" << (void *) temp << ">" << endl;
          strcpy(song1,temp);
          cout << "98. song1 = <" << song1 << ">" << endl;

          cout << "99. Printing out song: ";
          cout << song1 << endl;

        } while ( strcmp(song1,test) != 0 );


      cout << "After loop" << endl;
      cout << "Garbage: " << garbage << endl;
      cout << "Temp: " << temp << endl;
      cout << "line: " << line << endl;
      cout << "song1: " << song1 << endl;
      cout << "test: " << test << endl;

    }

  cout << "After breaking out of reading file loop" << endl;

}


Ok that's the code I tried to run with more cout's and found out that it did break out of the loop. Here are the results:

Code:
99. Printing out song: 15. Elevators (ONP 86 Mix) 96. line: <------> 97. temp = <6acc0> 98. song1 = <------> 99. Printing out song: ------ After loop Garbage: Track Listing: Temp: ------ line: ------ song1: ------ test: ------ Segmentation fault (core dumped)

So from what the last variables indicate, it should be at the end of the file. So I dont understand why it doesn't break out of the loop and print that last cout at the end of the program.

Did you think it wasn't breaking out of the small do/while loop or the big while loop that searches for infile.peek() != eof?
Last edited by LuciWiz : 27-Jan-2005 at 14:58. Reason: Please insert your C code betweem [c] & [/c] tags
  #4  
Old 27-Jan-2005, 12:10
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by swayp
Ok, I tried out your idea just now.


Did you think it wasn't breaking out of the small do/while loop or the big while loop that searches for infile.peek() != eof?

Here's how you figure it out:

Do you have cout statements at the beginning of the big loop?

Do you always test the return value of strtok()?

Try something like this:

CPP / C++ / C Code:
  while ( infile.peek() != EOF )
    {
      infile.getline(garbage,100);
      cout << "1. garbage: <" << garbage << ">" << endl;

      infile.getline(line,512);
      cout << "2. line: <" << line << ">" << endl;

      temp = strtok(line, " ");
      cout << "3. temp: <" << temp << ">" << endl;
      if (!temp) {
        cout << "4. strtok returned NULL" << endl;
        break;
      }
      strcpy(garbage,temp);
      cout << "5. garbage: <" << temp << ">" << endl;
      temp = strtok(NULL, "\n");
      if (!temp) {
        cout << "6. strtok returned NULL" << endl;
        break;
      }
      // etc

Note that giving a NULL src string to strcpy will (usually) cause a segfault.


Regards,

Dave
  #5  
Old 27-Jan-2005, 12:48
swayp swayp is offline
New Member
 
Join Date: Jan 2005
Posts: 25
swayp is on a distinguished road
Ok, I did what you said and here are the results:

For some reason it doesn't read the end of my file, which I dont understand. It goes back to the top of the loop and starts reading in the file, and then segfaults when it tries to strcpy a null string like u said.


Here's the top of the loop where it faults:
Code:
infile.getline(garbage,100); cout << "1. garbage: " << garbage << endl; infile.getline(line,512); cout << "2. line: " << line << endl; temp = strtok(line, " "); cout << "3. temp: " << temp << endl; if (!temp) { cout << "4. strtok returned NULL" << endl; break; }

Here is the output:
Code:
1. garbage: 2. line: 3. temp: strauss[~/fun]

Ok so it broke out of the loop without segfaulting, which is good. What I don't understand is why it tries to print out temp (its blank) but then doesnt print out the "endl". It goes right to my prompt without doing that. So why does it stop there? And how does it break out of the loop without printing cout #4?

Also, if I just keep that if statement in the loop, then it will break out without segfaulting, would there be a problem with my program or can I leave it like that. Of course I would like to know the answer to the previous question because I wanna know what's going on and why it is breaking out and why it is not reading the end of my file and trying to read in blank stuff.

swayp


EDIT:

I tried adding this to cout #3 to check it out:

Code:
cout << "3. temp: " << temp << " test" << endl;

And it gives me the same result. It doesnt print out " test", so the program breaks out (it does NOT seg fault) right before that.

That makes no sense to me LOL

Help oh wise dave
  #6  
Old 27-Jan-2005, 13:08
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by swayp
Ok, I did what you said and here are the results:



Also, if I just keep that if statement in the loop, then it will break out without segfaulting, would there be a problem with my program or can I leave it like that. Of course I would like to know the answer to the previous question because I wanna know what's going on and why it is breaking out and why it is not reading the end of my file and trying to read in blank stuff.

swayp

I have resisted the urge to comment on your program, because my main purpose was to get you to the point where you could see how to track down the point of the error.

Now, here's the drill:

It's sometimes difficult to see how to get a program to work with known good data. When you finally get it to spit out good results, the inclination is to quit the development. (That is, everything works with good input: go on to better things.)

It is usually vastly more difficult to see how to put special tests to make sure that the program does not misbehave when presented with data that is different than the programmer had in mind. (You can't prove a program is OK by testing, but you should test as many things as you can.) So: delete or comment out all of the extra cout statements that are cluttering up the program, but leave tests for eof and NULL return values from strtok(), since they prevent bad things from happening (we hope), and also may tell you when data in the input file is not correctly formatted.

What if a program has an extra blank line at the end? Does it still work, or does it bomb when going back through a loop? What if the data lines are not exactly what you had in mind. Etc., etc.

Here's a couple of general instructions.

When using getline(), make sure there is no eof after you get the line.

When using strtok(), test the return value to make sure it's not NULL (so you don't try to use that in a strcpy().

Now, totally unrelated to getline(), etc.:

When your program obtains storage by using new, it is your responsibility to delete everything before the program exits. If you don't, this is called a "memory leak", and, depending on the operating system, you will find that after running the program lots of times, you may run out of system resources. That's right: sometimes the memory that you obtained and didn't give back will never, ever be available again until you reboot your machine. Of course if your program ends with a segfault, there is no way of knowing whether the memory was returned (probably not would be my guess, but I don't really know).

By the way, there is no reason in the world to use dynamic storage allocation at all in this program. You could try
CPP / C++ / C Code:
  char line[512];
  char garbage[50];
  char artist[50];
  char title[50];
  char year[50];
  char song1[50];
  char test[7] = "------";
  char *temp;

Now, since this doesn't use new you don't have to worry about delete. The storage from these declarations is automatically returned to the operating system when the program exits (even with a segfault).

Regards,

Dave
  #7  
Old 27-Jan-2005, 13:22
swayp swayp is offline
New Member
 
Join Date: Jan 2005
Posts: 25
swayp is on a distinguished road
Ok sounds good.

This program is just a simple test program I'm running in trying to figure out how to read in this information. Eventually im gonna move the information to the bigger program that actually uses this information.

But I understand what you are saying and thanks for your help.
  #8  
Old 27-Jan-2005, 13:27
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by swayp
Ok sounds good.

This program is just a simple test program I'm running in trying to figure out how to read in this information. Eventually im gonna move the information to the bigger program that actually uses this information.


I typically spend 80% of programming and testing time on input/output (mostly input). Your decision to make sure that the input is absolutely correct before going on to a grander application is excellent!!!

Regards,

Dave
 
 

Recent GIDBlogDeveloping GUIs with wxPython (Part 2) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
warning cannot open 'extra/browscap.ini' for reading allelopath Apache Web Server Forum 1 08-Sep-2004 05:22
Damn RAM problems mrnobody Computer Hardware Forum 2 14-Aug-2004 20:29
Chaintech Geforce 5600 FX problems bartster74 Computer Hardware Forum 8 04-May-2004 13:16
reading a char* into struct data spike666 C Programming Language 7 19-Apr-2004 12:06
Having problems displaying a line of variable length using winio. warny_maelstrom C Programming Language 8 15-Feb-2004 11:56

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 18:33.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.