Thread: File I/O problem

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    30

    File I/O problem

    Hi.

    In the game that I am making, I use a genetic algorithm to evolve the enemies.

    The way I store the enemies "DNA" is in a text file.

    But, when I am reading the text file in and storing all the relevant bits of information something is going wrong and it is causing crashes at various different points in the game cycle.

    If I remove this bit of code, the game is fine. So I am sure that this section is the cause of all the crashes.

    I suspect that it is the while loop that uses .fail(), but I'm not sure.

    Can anyone see why this code isn't working properly?

    Any advice/comments/suggestions are much appreciated.

    Here is the code, and an example of the content of the text file:

    Code:
    ifstream file_to_read("DEAD.txt");
    
      while (!file_to_read.fail()) {
    
        char chromo_char_read[12];
    
        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();
    And the file it is reading in and using looks like this:

    Code:
    111111111111_50
    111111191111_73
    222222222222_20
    223222322222_83
    222222222222_98
    222222221122_18
    222222222312_97
    222222222222_307
    122221222222_102
    111111191111_548

    I'm really grateful for any help. Cheers.

  2. #2
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    get() adds a '\0' character after reading n-1 characters. In this line:

    file_to_read.get(chromo_char_read, 14, '_');

    You are asking to have 13 characters read into your array unless a '_' character is encountered first, then stop there. Since your text file contains 12 chars followed by a '_', 12 chars are read into your array, and then a '\0' is added at index position 12(the 13th element of the array), which is out of bounds. That may or may not be a problem later.

    Also, this looks suspect:
    Code:
    chromosome_int_array.push_back(chromo_char_read);
    An array name is an address, i.e. it's like a pointer, so you are inserting a pointer into a vector of type int? A pointer to any type and an int are incompatible types.
    Last edited by 7stud; 02-19-2006 at 04:01 PM.

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    OK. So, I changed it to...

    Code:
    file_to_read.get(chromo_char_read, 13, '_');
    But it still crashes. Am I being really stupid here?

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    What does changing it to 13 solve? You still have the exact same problem. The 2nd parameter of get() should be the length of your array. However, get() reserves the last spot for a '\0' so with your current array length, you will only read in 11 chars.

    Do you want your char array to be null terminated, so that you can treat it like a string? get() makes your char array null terminated.
    Last edited by 7stud; 02-19-2006 at 04:06 PM.

  5. #5
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Oh, OK...sorry, just read your other bit.

    "chromosome_int_array" is a vector of strings. I've been meaning to change the name, it's confusing and stupid.

    I'll just add that 2nd parameter of get() now...

  6. #6
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Yes, I wanted to treat it as a string...so get() is the correct function to use, eh?
    Last edited by Onions; 02-19-2006 at 04:09 PM. Reason: Misread something

  7. #7
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    If I change it to...

    Code:
    file_to_read.get(chromo_char_read, 13, '_');
    The game freezes when it tries to create a new enemy.

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    "chromosome_int_array" is a vector of strings
    Then why don't you use string types to read the input? Char arrays are a pain in the butt to deal with, and if you are just going to convert them to a string type anyway, use string types to begin with. If you use string types to read in the input, you don't have to worry about making sure there is a '\0' on the end. Just use getline() with '_' as the delimiter which is the 3rd parameter:


    string input;
    getline(file_to_read, input, '_');

    That also causes the '_' to be discarded, so the next read will start at the first char after '_'.

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If you want to use a char array, and you know you have to read in 12 chars, and you also want the array to end with a '\0', then what length should your array be? 12 chars + '\0' = ?

  10. #10
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Right, OK...I've switched it to strings. And it still crashes after a short while.

    Looking at what happens, it seems it is reading in a blank line from the text file.

    If there are 6 lines of numbers, it is looping through 7 times and getting chromosomes and fitnesses. Is this related to fail(), do you think?

    By the way, I appreciate the time you're spending helping me out here. Really.

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If there are 6 lines of numbers, it is looping through 7 times and getting chromosomes and fitnesses. Is this related to fail(), do you think?
    Yes, because when you read the last line, everything is fine, so when you jump back up to the while condition it won't evaluate to false. It's only when you try to read the 7th time inside the loop that things go wrong. When you jump back up to the while conditional thereafter, the condition fails and the loop ends, but that's too late--you've already acted on your bad input.

    That is why your read statement should always be the while conditional. Most of the functions that read from a file have a return value that is the ifstream object, and the ifstream object will evaluate to false if you can't read from the file anymore. Then, the loop will end immediately and prevent you from taking action inside the loop with bad input.
    Last edited by 7stud; 02-19-2006 at 04:27 PM.

  12. #12
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    So, how do I stop it from reading in a blank chromosome and a blank fitness? It can't be good having them in the string vectors.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Make your read statement(s) the while conditional, e.g.
    Code:
    while( getline(....) && getline(...)  )
    {
    
        //do stuff with the input
    }
    Last edited by 7stud; 02-19-2006 at 04:31 PM.

  14. #14
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Mate, sorry I'm being such a dumbass here...but I don't understand what you mean by that.

    Can you explain what you mean exactly?

  15. #15
    Registered User
    Join Date
    Sep 2005
    Posts
    30
    Ah, OK.

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