Thread: reading strings from a binary .txt file

  1. #1
    Master of Puppets rwmarsh's Avatar
    Join Date
    Feb 2006
    Location
    Texas
    Posts
    96

    reading strings from a binary .txt file

    My program saves customer data to a .txt file in binary. Fields such as name and address are typed in as a C++ string, converted to a C style char array, and saved to disk (since the compiler will not let me save a c++string, only a char array). These same fields can also be loaded into a C style char array and converted back to a string (for the ease of manipulation). I am using stringstreams to do the conversions but I am getting no results.

    Code:
    //  save customer profile to disk
    
    int saveprof()
    {
        ofstream fcust(c:\\cust_data.txt",ios::binary | ios::app);
        if (fcust.fail()) 
        { cout<<"\nCannot open library file!\a"; }
        else
        {
            string temp;
            temp.assign(custinfo.cust_name, 0, 26);
            fcust.write(temp.c_str(),26);
            temp.assign(custinfo.cust_address, 0, 26);
            fcust.write(temp.c_str(),26);
            temp.assign(custinfo.cust_city, 0, 16);
            fcust.write(temp.c_str(),16);
            temp.assign(custinfo.cust_state, 0, 3);
            fcust.write(temp.c_str(),3);
            fcust.write(reinterpret_cast<char*>(&custinfo.cust_zip), sizeof(int));
            temp.assign(custinfo.cust_contact, 0, 26);
            fcust.write(temp.c_str(),26);
            temp.assign(custinfo.cust_phone, 0, 13);
            fcust.write(temp.c_str(),13);
            cout<<"\nFile saved";
            fcust.close();
        }
        return 0;
    }
    
    
    //  load customer profile from disk
    
    int findprof()
    {
        ifstream fcust("c:\\cust_data.txt", ios::binary);
        if (fcust.fail())
        { cout<<"\nCannot open library file!\a"; }
        else
        {
            istringstream sstream(ctemp);
            getline(sstream, custinfo.cust_name);
            sstream.str("");
            fcust.read(ctemp,26);
            sstream.str(ctemp);
            getline(sstream, custinfo.cust_address);
            sstream.str("");
            fcust.read(ctemp,16);
            sstream.str(ctemp);
            getline(sstream, custinfo.cust_city);
            sstream.str("");
            fcust.read(ctemp,3);
            sstream.str(ctemp);
            getline(sstream, custinfo.cust_state);
            sstream.str("");        
            fcust.read(reinterpret_cast<char*>(&custinfo.cust_zip), sizeof(int));
            fcust.close();
        }
        return 0;
    }
    The customer name comes up just fine but all the other string fields come up blank. (the zip code works fine, also)

    Using DEV-C++ Under Windows XP

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Try the FAQ under such subjects as "getting a line from the user (C++)".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    If your 'customer' or whatever class is just 'plain old data', or something like this:

    Code:
    struct customer
    {
    	char cust_name[26];
    	char cust_address[26];
    	char cust_state[3];
    	char cust_contact[26];
    	char cust_phone[13];
    	int cust_zip;
    }
    Then you can just:

    Code:
    	// write
    
    	std::ofstream o("test.txt", std::ios::binary);
    
    	customer c(...);
    
    	o.write(reinterpret_cast<char*>(&c), sizeof(c));
    
    	// read
    
    	std::ifstream i("test.txt", std::ios::binary);
    
    	customer c;
    
    	i.read(reinterpret_cast<char*>(&c), sizeof(c));

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Why are you using "binary" files when handling text? Wouldn't it be way easier using text methods from the beginning?

    Code:
    struct CInfo
    {
      std::string Name;
      std::string Address;
      std::string Phone;
    };
    
    void Save(const CInfo& Info)
    {
      std::ofstream File("SomeFile.txt");
    
      File << Info.Name << std::endl;
      File << Info.Address << std::endl;
      File << Info.Phone << std::endl;
    }
    
    void Load(CInfo& Info)
    {
      std::ifstream File("SomeFile.txt");
    
      std::getline(File, Info.Name);
      std::getline(File, Info.Address);
      std::getline(File, Info.Phone);
    }
    (this, of course, assumes that each string field occupies no more than 1 line)
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And why are you giving binary files a .txt extension?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Master of Puppets rwmarsh's Avatar
    Join Date
    Feb 2006
    Location
    Texas
    Posts
    96
    Why are you using "binary" files when handling text? Wouldn't it be way easier using text methods from the beginning?
    Yes, it would be easier to use text methods, but then I would not learn how to work with binary methods.

    The point is I have heard that you can use stringstreams to convert from a char array to a string, but everything I have tried just produces an empty string. Is it possible to do this or is there an easier way? I have searched and googled until I was blue in the face and could not come up with anything.....
    Using DEV-C++ Under Windows XP
    +------------------------------+

    "No! Do, or Do Not. There is no Try..."

  7. #7
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    No need for stringstreams, std::string has a constructor that takes a char pointer:
    Code:
    char CharArray[32];
    std::string String = CharArray;
    Make sure the array ends with a NULL terminator ( '\0' ).
    If this is not the case, you could use a temporary buffer:
    Code:
    char CharArrayWithNoNullTerminator[32];
    std::vector<char> TempBuffer;
    TempBuffer.resize(32 + 1);
    std::memcpy(&TempBuffer[0], CharArrayWithNoNullTerminator, 32);
    TempBuffer[32] = '\0';
    std::string String = &TempBuffer[0];
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  8. #8
    Master of Puppets rwmarsh's Avatar
    Join Date
    Feb 2006
    Location
    Texas
    Posts
    96
    Now, I could swear I did that before and it did not work.... Now it does....

    Maybe I just THOUGHT I did that... Oh well, Thanks for the help! I knew there was an easier way... Maybe I just need to get some sleep..........
    Using DEV-C++ Under Windows XP
    +------------------------------+

    "No! Do, or Do Not. There is no Try..."

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Quote Originally Posted by Magos

    std::string has a constructor that takes a char pointer...Make sure the array ends with a NULL terminator ( '\0' ). If this is not the case, you could use a temporary buffer
    Code:
    char CharArrayWithNoNullTerminator[32];
    std::vector<char> TempBuffer;
    TempBuffer.resize(32 + 1);
    std::memcpy(&TempBuffer[0], CharArrayWithNoNullTerminator, 32);
    TempBuffer[32] = '\0';
    std::string String = &TempBuffer[0];
    No need for all that. There is a string constructor that can handle non null terminated char arrays, as well:
    Code:
    const int size = 3;
    char NoNullTerminator[size] = {'y', 'e', 's'};
    	
    string myString(NoNullTerminator, size);
    cout<<myString.c_str()<<endl;
    ...and you can do more straight forward things like this as well:
    Code:
    string myString1;
    myString.assign(NoNullTerminator, size);
    cout<<myString.c_str()<<endl;
    
    string myString2;
    myString2.append(NoNullTerminator, size);
    cout<<myString2.c_str()<<endl;
    
    string myString3;
    myString3.insert(myString3.end(), NoNullTerminator, NoNullTerminator + size);
    cout<<myString2.c_str()<<endl;
    Last edited by 7stud; 03-05-2006 at 09:32 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading Multiple Multi-Part Strings From a Text File
    By bengreenwood in forum C++ Programming
    Replies: 2
    Last Post: 06-02-2009, 10:43 AM
  2. reading .txt file
    By vijay85 in forum C Programming
    Replies: 5
    Last Post: 03-09-2009, 04:07 PM
  3. reading from a file + list of strings
    By stewie1986 in forum C Programming
    Replies: 2
    Last Post: 12-06-2007, 11:59 PM
  4. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM