Thread: File I/O problem

  1. #16
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    I've changed it to this, and it STILL crashes.

    Code:
     while (getline(file_to_read, chromosome_int_read, '_') && getline(file_to_read, fitness_string_read)) {
    God, this is annoying. If I remove this loop, the whole game works fine. This is driving me nuts.

  2. #17
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    What type is chromosone_int_read and what type is fitness_string_read?

    When I read from your file in the while conditional using getline(), and then inside the while loop display what was read in, this is the output I get:
    Code:
    111111111111 50
    111111191111 73
    222222222222 20
    223222322222 83
    222222222222 98
    222222221122 18
    222222222312 97
    222222222222 307
    122221222222 102
    111111191111 548
    Last edited by 7stud; 02-19-2006 at 08:15 PM.

  3. #18
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    They are both strings.

    I have tried reading in a different file using the same sort of method, and that crashes the game as well. I can't seem to read in anything from a text file without it causing problems.

  4. #19
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Quote Originally Posted by Onions
    Hi.

    Code:
    ifstream file_to_read("DEAD.txt");
    
      while (!file_to_read.fail()) {
    This jumps out at me as the first problem - Don't wait for the stream to fail before ending the loop, that is asking for trouble!

    instead, simply use
    Code:
    while(file_to_read) {
    Also, "file_to_read" is perhaps poorly named - it is not a file, it is an istream - so it should be treated in exactly the same way as you would treat any other istream. I believe this could be the source of some confusion.

    Quote Originally Posted by Onions
    Code:
        char chromo_char_read[12];
    Someone else has already pointed out an error here, but why use a C-style string at all, and not a std::string? - you can use c_str() if you ever need a null-terminated char array.

    Quote Originally Posted by Onions
    Code:
        char junk_sep_char;
    
        string fitness_string_read;
    
        file_to_read.get(chromo_char_read, 14, '_');      
    
       file_to_read.get(junk_sep_char);
    
        getline(file_to_read, fitness_string_read);
    
        chromosome_int_array.push_back(chromo_char_read);
    
        fitness_string_array.push_back(fitness_string_read);  
    
      }
    
      file_to_read.close();
    There is no need to close the stream - When file_to_read goes out of scope and its lifetime ends, the istream destructor will perform all the necessary steps.
    Last edited by Bench82; 02-20-2006 at 05:04 AM.

  5. #20
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Well, the code now looks like this...

    Code:
    ifstream file_to_read("DEAD.txt");
    
    string chromosome_string_read;
    chromosome_string_read = "";
    
    string fitness_string_read;
    fitness_string_read = "";
    
      while (getline(file_to_read, chromosome_string_read, '_') && getline(file_to_read, fitness_string_read)) {
    
        chromosome_string_array.push_back(chromosome_string_read);
    
        fitness_string_array.push_back(fitness_string_read);   
    
      }
    
      file_to_read.close();
    But it still crashes.

    Any thoughts?

  6. #21
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Quote Originally Posted by Onions
    Well, the code now looks like this...

    Code:
    ifstream file_to_read("DEAD.txt");
    
    string chromosome_string_read;
    chromosome_string_read = "";
    
    string fitness_string_read;
    fitness_string_read = "";
    
      while (getline(file_to_read, chromosome_string_read, '_') && getline(file_to_read, fitness_string_read)) {
    
        chromosome_string_array.push_back(chromosome_string_read);
    
        fitness_string_array.push_back(fitness_string_read);   
    
      }
    
      file_to_read.close();
    But it still crashes.

    Any thoughts?
    Your while loop is still overflowing past the end of your istream (you use getline() twice.

    try the following
    Code:
    while (file_to_read)
      std::string s;
      std::string::size_type start(0), index;
      std::getline(file_to_read, s);
    
      index = s.find('_');
         // find character '_' in s
         // Error checking to make sure index is valid should go here
    
      std::string chromosome_read(s, start, index);
         // chromosome_read initialised with, at most, 'index' number of
         // characters taken from s, starting from s[start]
    
      std::string fitness_read(s, index);
         // fitness_read is initialised by the characters from s
         // starting from s[index]

  7. #22
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Hmm...it crashes the moment it tries to use that loop.

    Why exactly is it a problem if you use getline() twice?

  8. #23
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I can't seem to read in anything from a text file without it causing problems.
    Start a new program to use as a test. Can you write a while loop that will print out the output I posted without crashing?

    Once you can do that, put all the strings in a vector as you read them. After you are done reading in all the input, use the vector to display the strings.

    You have to be able to do those two tasks before continuing on.

    Code:
    string chromosome_string_read;
    chromosome_string_read = "";
    Can you think of a more succinct way to write that?
    Last edited by 7stud; 02-20-2006 at 11:51 AM.

  9. #24
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Sorry, that wasn't quite a compilable snippet of code - I should have added that the comment about error checking wasn't optional - it crashes because you do not check for errors in finding "index" before manipulating the string (which doesn't exist on the final run)

    the issue with your usage of getline isn't the actual getline function, but the way you use it to assign to a string without error checking. Your while loop makes the assumption that the line will always contain a '_' char.
    The final time your while loop executes, there will in fact be an empty string - so the attempt to assign "all characters up to '_' " will result in overflow - because '_' is never found.

    This same reason is why you must check for the validity of index after the find - because if there is no '_' found, you will get the overflow


    Find returns a value called 'npos' when it can't find a match - the answer is to do something like
    Code:
    if (index == std::string::npos)
      break; // out of the while loop
    before proceding to do anything with your strings.

    Actually, there are less hackish ways to handle npos than a break in the middle of the loop, but that is a quick and easy way for this scenario.
    Last edited by Bench82; 02-20-2006 at 12:01 PM.

  10. #25
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Please ignore what Bench82 has posted.

  11. #26
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Yeah, I can do it in a new program. With a vector too.

    [I'm talking about what 7stud described]

    I just don't get this at all.

    When an enemy is destroyed, it's chromosome and fitness is written to the DEAD.txt file in the "12INTS_FITNESSINT" format. This should then be read in, stored and messed around with.

    If I manually set 200 chromosome strings and 200 fitness strings, all the rest of the genetic algorithm stuff works. It converts it all to integers, mutates some values, returns the new chromosome and that is then implanted into a new enemy.

    The only thing that it refuses to do is actually get those 200 (or whatever) strings from the DEAD.txt file. I really have scoured and debugged the whole rest of the program, and it all comes down to this loop. Take it out - brilliant. Put it in - random crashes for, literally, a dozen different reasons. Sometimes it can't use a vector properly, sometimes it tries to update an enemy that doesn't exist...it will crash for anything.

    Can you think of any reason why this might be happening?
    Last edited by Onions; 02-20-2006 at 12:01 PM.

  12. #27
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If I manually set 200 chromosome strings and 200 fitness strings,
    How are you doing that? If you manually assign one of your strings to a string variable, and then read the same string from the file, you can test that they are the same:
    Code:
    if(manualString == inputString)
      cout<<"yes";
    Last edited by 7stud; 02-20-2006 at 12:07 PM.

  13. #28
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    I commented out the loop which reads in the chromosomes and fitness integers, and just shoved this there:

    Code:
    string chromosome = "222222222222";
    
    for (int i = 0; i < 215; i++) {
    chromosome_int_array.push_back(chromosome);
    }
    
    
    string fitness = "2134";
    
    for (int i = 0; i < 215; i++) {
    fitness_string_array.push_back(fitness);
    }
    So, basically I just "faked" that 200 chromosomes and fitnesses had been read in from the DEAD file.

    And the frustrating thing is that it works perfectly! It's this that has lead me to focus entirely on that loop. If this hard-coding method works, surely it means that the problem is 100% to do with that file reading loop, right?

  14. #29
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Quote Originally Posted by 7stud
    Please ignore what Bench82 has posted.
    You will find that the snippet of code I posted works fine once error checking is introduced. Admittedly I should not have posted the original message without that.

  15. #30
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Put those exact same strings in your file 215 times, and see if it works.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  2. File i/o problem
    By tezcatlipooca in forum C++ Programming
    Replies: 18
    Last Post: 01-01-2007, 09:01 AM
  3. File I/O problem
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 12
    Last Post: 09-03-2005, 12:14 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM