#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    2
    Rep Power
    0

    reading info from a file to a structure


    Alright...I read the thread 'reading into a structure' and I'm still not very clear on how to solve the problem. I don't really understand c++ jargon :o

    Anyhow, I am trying to read names/emails from a file into a structure. When I execute the file though, the first few names come out alright, but after a couple of lines, the names and/or email addresses have random gibberish in the middle of it.

    Ex. It comes out like this .. (no, these aren't real people)

    Ned Allen allen7@hotmail.com
    Timothy Bender timben@yahoo.com
    Sara Breck breB nder timben@yahoo.com
    Sara Breck breB
    ck@hotmail.com

    Um, yeah. here's my code. Could anyone point me in the right direction? I'm not quite sure where I'm going wrong here...

    Code:
    struct Info
    {
    	char name[50];	
    	char email[50];
    };
    
    
    int main()
    {
    	fstream emails;
    	Info i;
    
    	emails.open("emails.txt", ios::in | ios::binary);
    	
    	emails.read((char *)&i, sizeof(i));
    	
    	while (!emails.eof())
    	{
    		cout << i.name << "  " << i.email << endl;
    		emails.read((char *)&i, sizeof(i));
    	}
    		
    	
    	
    
    	cout << "End of file.";
    	emails.close();
    }
  2. #2
  3. No Profile Picture
    Dinesh_P_V
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    India
    Posts
    259
    Rep Power
    0
    Are you sure that you are writing in the same format in the file email.txt as you read it.

    The following code will work fine

    //Writing data into the file
    #include<string.h>
    #include<fstream.h>
    #include<iostream.h>
    struct Info
    {
    char name[50];
    char email[50];
    };


    int main()
    {
    fstream emails;
    Info i;

    emails.open("emails.txt", ios::out | ios::binary);
    strcpy(i.name,"Dinesh");
    strcpy(i.email,"dinesh@dinesh.dinesh");
    emails.write((char *)&i, sizeof(i));
    emails.close();
    }


    //Reading data from the file

    #include<string.h>
    #include<fstream.h>
    #include<iostream.h>
    struct Info
    {
    char name[50];
    char email[50];
    };

    int main()
    {
    fstream emails;
    emails.open("emails.txt", ios::in | ios::binary);
    Info i;
    emails.read((char *)&i, sizeof(i));
    while (!emails.eof())
    {
    cout << i.name << " " << i.email << endl;
    emails.read((char *)&i, sizeof(i));
    }
    cout << "End of file.";
    emails.close();
    }

    When you are getting some garbage while reading such files then it is due to the fact that you don't write into the file in a correct format.
    HTH
    -Murugesan
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Sammi, part of the issue is that different platforms, different compilers, and different compiler settings can cause a binary struct to be written differently to a file. The main reason is that in order to make accessing the fields within the struct more efficient, the spaces between fields can get padded with extra bytes so that all the fields line up just right for the data bus. So unless you can keep all those things -- and more that I can't think of right now, like byte order of integers -- exactly the same, there is no guarantee that your approach will work. For example, it will work if the same program first creates the file and then reads it back in.

    What's normally done is to create the input file in a different format that your program can easily read. Comma-delimited text files (eg, .CSV files in Excel) are popular. Or fixed-column text files. The main thing is that you should read in a line and then extract each field's data rather than trust that that memory image in that file will match exactly what your program will expect.


    Now, more specifically, your problem appears to be due to "garbage characters" in a buffer. Have you looked at the input file itself? Does it contain the garbage you are reading? If so, then whoever created that file had not properly terminated Sara's name with a NUL ('\0'). And it does seem odd that the first ten characters of the last good line get replaced with "Sara Breck breB" and that Sara Breck's name is itself ten characters long.

    You should also view a hex dump of the input file to see whether the strings are properly terminated and also to see whether there is any padding between the fields. You should also create your own test file to see what kind of padding your program inserts. Under Linux od /x or xxd would provide a hex dump -- watch out for byte pairs getting swapped using od. Or under Windows opening the file with debug and using the d command repeatedly to step through the file; use the q command to quit out of debug.

    One quick test for incompatible padding would be to output to the console the size of the Info struct, then dividing the input file's filesize to see if it divides evenly . If your answer is not the number of Info objects and no remainder, then the padding is different.
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    2
    Rep Power
    0
    First of, thanks Murugesan and Dwise for the helpful hints.
    I am doing this program for an assignment and our professor gave us the file to use...which is why I didn't write it first.

    I suppose I could do my own thing and write to the file first. :D

    But I will try your quick test for incompatible padding Dwise. Thank you so much!

    I really appreciate what information you guys gave me. I didn't know that not writing to the file would cause such a problem... yeh, I'm so new to this stuff.

    Thanks again!
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    BTW, always keep a copy of the original file tucked away somewhere safe as a back-up. Just in case you accidently munge the copy you're working with. It's sure saved me a lot of times.

IMN logo majestic logo threadwatch logo seochat tools logo