Thread: File I/O with arrays

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    27

    File I/O with arrays

    Yet another newbie-ish problem.... this time slightly more advanced.

    I'm having a bit of trouble reading information as text from a file.... The information involves three different sets of integers, two normal, and one an array, like so:

    Code:
    100
    30
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111131111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111131111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111222222221111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111131111111111111111111111111222222221111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111131111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111113111111111111111111111111
    1111111111111111113111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111311111111111111111111111111111111111111111111111111
    1111111111111111111111111111131111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111311111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    Yes, it's a lot, but I'm trying to hard-code something for testing.

    My file I/O operation currently reads like so:-

    Code:
    int location::fileread(char filename[10])
    {
        ifstream a_file ( filename );
        if ( !a_file.is_open() ) {
        cout<<"File could not be opened./n";
        return 0;
          }
    else {
        a_file>>mapx;                              //read the first value, the x-value
        a_file>>mapy;                              //read the second value, the y-value
        a_file>>terrain[mapx][mapy];      //store the long section of 1s, 2s, and 3s in terrain[100][30]
        return 1;}
    }
    This results in me getting a blank screen with no information whatsoever. I don't know if this means that the x and y values are being read but the array isn't, or if the whole lot is horribly wrong (the results would, I think, be pretty much the same). I'm pretty sure the problem lies in the array. Does instreaming read a single character? Multiple characters? The entire line? Is there any way to alter this?

    It's probably a really stupid question, but any help would be greatly appreciated!

  2. #2
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    Erm, why are you returning 1 after the else statement as that means that there is an error. Return 1 if the file can't be opened.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > a_file>>terrain[mapx][mapy]
    This refers to the element just off the end of the array

    Maybe
    Code:
    for ( int r = 0 ; r < mapy ; r++ ) {
      for ( int c = 0 ; c < mapx ; c++ ) {
        a_file>>terrain[r][c];
      }
    }
    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
    Sep 2006
    Posts
    27
    To be honest, I just prefer it that way.... the main() setup goes something like so:

    Code:
    int main()
    {
        char mapf[10];
        cout<<"Enter map file:\n";
        cin>>mapf;
        if (locate.fileread(mapf) == 1){
        clrscr();
        charx = mapx/2;
        chary = mapy/2;
        mapprint(mapx, mapy);
        do {
            input();
            }
            while (input() != 0) ;
            clrscr();
            }
            else {
        cursorpos(0,0);
        cout<<"Goodbye!";}
    }
    I just have a thing about 1 being 'true' and 0 being 'false'. It's not that much trouble to change, though, if you think I should.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Hmm, thanks for the advice Salem, but it's still not loading correctly . Maybe I should figure out how the C commands work rather than mess around with the C++ commands... although the C version seems so much more complex.

    EDIT:
    I've figured out how to manage it, rather than storing each variable in a two dimensional way in the file itself, I have to store it one on top of the other (like
    1
    1
    1
    1
    1
    1
    1
    etc...) and then read it like that. Unless there's some way to integrate strings and integers.... anyway, for the time being, problem solved.
    Last edited by 20,000leeks; 09-17-2006 at 07:10 AM.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Maybe
    Code:
    for ( int r = 0 ; r < mapy ; r++ ) {
      for ( int c = 0 ; c < mapx ; c++ ) {
        a_file>>terrain[r][c];
      }
    }
    Maybe not. It looks like all of the digits are intended to be unique entities but they're not separated by whitespace. a_file>>terrain[r][c] is unlikely to work as expected in this situation. Something more like this would work if I'm judging the file properly:
    Code:
    a_file>> first;
    a_file>> second >> ws;
    
    for ( int i = 0; i < mapy; i++ ) {
      for ( int j = 0; j < mapx; j++ )
        terrain[i][j] = a_file.get() - '0';
    }
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Hmm, it *almost* works. I think because there's a white space on the end of each line, that makes things a little more complex, so I tried:

    Code:
    for ( int i = 0; i < mapy; i++ ) {
           for ( int j = 0; j < mapx; j++ )
            if ( j < mapx){
            terrain[j][i] = a_file.get() - '0';
            }
            else a_file>> terrain [j][i];
           }

    but it still comes out on a slant (like this

    Code:
     .................................................
    . ................................................
    .. ...............................................
    ... ..............................................
    .... .............................................
    ..... ............................................
    ...... ...........................................
    ....... ..........................................

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You need to read in the '\n', I think.
    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.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Ah, so there are linebreaks in the file itself. Okay, how about this:
    Code:
    for ( int i = 0; i < mapy; i++ ) {
      for ( int j = 0; j < mapx; j++ ) {
        char ch;
    
        if ( !a_file.get ( ch ) ) {
          // Handle an input error
        }
    
        if ( ch != '\n' )
          terrain[i][j] = ch - '0';
      }
    }
    My best code is written with the delete key.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You could just do this:
    Code:
    for ( int i = 0; i < mapy; i++ ) {
      for ( int j = 0; j < mapx; j++ )
        terrain[i][j] = a_file.get() - '0';
    
      while(a_file.get() != '\n' && !a_file.bad());
    }
    .bad() might not be the best function to use however.
    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.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Hmm, I tried
    Code:
    for ( int i = 0; i < mapy; i++ ) {
           for ( int j = 0; j < mapx; j++ )
           if (a_file.get()!='\n'){
            terrain[j][i] = a_file.get() - '0';
            }
            else
            {j = mapx;
            }
    but that seemed to cut out parts of the file.

    Code:
    for ( int i = 0; i < mapy; i++ ) {
      for ( int j = 0; j < mapx; j++ )
        terrain[i][j] = a_file.get() - '0';
    
      while(a_file.get() != '\n' && !a_file.bad());
    }
    didn't load the map at all for some reason :S

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >You could just do this:
    Handling the linebreak outside of the inner loop is definitely a better solution, but I'd still want some error checking:
    Code:
    for ( int i = 0; i < mapy; i++ ) {
      for ( int j = 0; j < mapx; j++ ) {
        char ch;
    
        if ( !a_file.get ( ch ) ) {
          // Handle an input error
        }
    
        terrain[i][j] = ch - '0';
      }
    
      a_file.ignore();
    }
    My best code is written with the delete key.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Aha! Problem solved! Thanks a lot, I'd probably have resorted to using a single-column file otherwise....

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I forgot about ignore() . . .

    I'm sure you've fixed this by now, but here's an earlier line you posted:
    Code:
    cout<<"File could not be opened./n";
    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.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Ah, yes, I noticed that one about five minutes after posting it.... I guess there's an upside to uncomplicated applications, you catch typos faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Subtle(?) File I/O Problem
    By cecomp64 in forum C Programming
    Replies: 9
    Last Post: 07-16-2008, 11:39 AM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  4. File I/O Question
    By Achy in forum C Programming
    Replies: 2
    Last Post: 11-18-2005, 12:09 AM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM