Thread: Reading char arrays from a binary file

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    89

    Reading char arrays from a binary file

    Nothing I have tried works...Unfortunately the tutorials on the net are not any help. They just give you a few lines of code without hardly any expianation. And none tell you how to read in a character array.

    This is what I am trying to read in:
    "Iron Dagger"
    using:
    Code:
    char* name;
    in.read(name, sizeof(name));
    std::string newname(name);
    Reads only to the first white space encountered

    using:
    Code:
    char* name;
    in.getline(name, sizeof(name), '\n');
    std::string newname(name);
    Reads the entire file in one lump...or so I think...it just outputs a bunch of crap.

    anyone have any suggestions.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    Don't use character arrays. Use std::string.

    Code:
    std::ifstream in("my_file.ext", "r");
    if(in.is_open())
    {
       std::string name;
       std::getline(in, name, '\n');
    }

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Yes, use a std::string and stop messing with char pointers which you don't allocate memory to.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Does your file indicate how many characters are in the string? In a binary file, you would need to know how many characters if you want to read the entire string in at once.

    Does your file have the terminating null character written to it? If you created the file by calling write to a binary stream then it might, but if you just typed it in a text editor it probably doesn't. If it has the terminating null, you should read in one character at a time and stop when you reach a null.

    If you don't have a size and you don't have a terminating null, then you can't really read in teh string from a binary file. Are you sure you want to use a binary file?

    In your code examples, name is an uninitialized pointer. If you want to read into a character array, make it an array with a given size.

    You can't read into a string from a binary file, so using a C style string is the way to go if you do in fact have to read the string from the binary file.

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    I have already tried it your way Desolation...it didnt work either. I am not sure if the getline function works with binary files.

    Does your file have the terminating null character written to it? If you created the file by calling write to a binary stream then it might, but if you just typed it in a text editor it probably doesn't.
    It should, cuz I did create the binary file using the write() function

    If it has the terminating null, you should read in one character at a time and stop when you reach a null.
    How do I do that? terminating null = \0 right?
    But to use it as a delimiter I would have to use the getline function...and that has been causing me major problems.

  6. #6
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Yes, use a std::string and stop messing with char pointers which you don't allocate memory to.
    How do I allocate memory when I dont knwo how much to allocate?

    I want my LoadLevel Function to be able to read in any char array size.

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Does your file indicate how many characters are in the string? In a binary file, you would need to know how many characters if you want to read the entire string in at once.
    so lets say I did this: (psuedo code...sort of)
    Code:
    std::string = "Iron Dagger";
    int size = 12;
    
    ofstream out;
    out.write((char*)&size, sizeof(int));
    
    const char* newname = name.c_str();
    out.write(newname, sizeof(name));
    
    ifstream in;
    
    int size = 0;
    in.read((char*)&size, sizeof(int));
    
    char name[size];
    in.read(name, sizeof(name))
    Would that work?
    Last edited by eaane74; 11-19-2007 at 05:46 PM.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    You're probably better of writing a text file, and putting each string on a separate line. Then you can use getline() to read in the string:
    Code:
    int size;
    std::string name;
    in >> size;
    
    getline(in, name)
    Or you could delimit the string from other data written to the file with a comma, and use:
    Code:
    int size;
    std::string name;
    
    in >> size;
    getline(in, name, ',')
    If you're going to use write() and read() with a binary file, then you must read exactly the number of characters written, which your example isn't. Well actually it is, but what you should use instead of sizeof(name) is name.length(). That should work for a binary file.
    Last edited by swoopy; 11-19-2007 at 06:07 PM.

  9. #9
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Ok so how about this then:

    Code:
    int stringlength = 0;
    in.read((char*)&strengthlength, sizeof(int));
    
    for(int x = 0; x < stringlength; x++)
    {
         in.read(name[x], sizeof(name[x]));
    }
    Or something to that effect.


    I want to avoid using a text file. if possible.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> so lets say I did this: (psuedo code...sort of)
    Yes. Almost. The idea is correct.

    >> int size = 12;
    I would set the size variable equal to the value returned by the string's size() or length() function to make sure it is accurate. You don't have to output the null, but if you do you'd want to add 1 to that value.

    >> out.write(newname, sizeof(name));
    Don't use sizeof(name), because that will only be the size of the pointer. Use the size variable that you just created.

    >> char name[size];
    You aren't allowed to declare an array with a size that isn't known until compile time in C++. Your compiler might allow it, but it is technically not allowed in C++. One solution is to use a vector and then assign it to the string:
    Code:
    vector<char> name(size);
    in.read(&name[0], size);
    std::string str(name.begin(), name.end());

    >> in.read(name[x], sizeof(name[x]));
    If you wanted to go that route, you should use get() instead to get a single character at a time, but as long as you're sticking to binary then I'd use the pseudo code you had earlier with the above changes.

  11. #11
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Ok

    Code:
    int namelength = name.length();
    const char* newname = name.c_str;
    out.write(newname, namelength);

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Pretty much. What about the read?

  13. #13
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Code:
    int namelength = name.length();
    const char* newname = name.c_str();
    out.write((char*)&namelength, sizeof(int));
    out.write(newname, namelength);
    
    int namelength = 0;
    in.read((char*)&namelength, sizeof(int));
    char* newname;
    in.read(newname, namelength);
    std::string name(newname);
    Last edited by eaane74; 11-19-2007 at 06:42 PM.

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    You probably want to use what Daved posted for the read, as it will work with any length string. So changing the names a bit:
    Code:
    vector<char> temp(namelength);
    in.read(&temp[0], namelength);
    std::string name(temp.begin(), temp.end());
    //Now name contains your string

  15. #15
    Registered User
    Join Date
    Jan 2007
    Posts
    89
    Ok...This is my first time working with binary files...hadn't thought about going the vector route

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ ini file reader problems
    By guitarist809 in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2008, 06:02 AM
  2. The Interactive Animation - my first released C program
    By ulillillia in forum A Brief History of Cprogramming.com
    Replies: 48
    Last Post: 05-10-2007, 02:25 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM