Thread: Read .txt file into 2D array.

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    25

    Read .txt file into 2D array.

    Ok, I am making a puzzle game. For my function loadPuzzle, I want to read in a random puzzle to a 2d array. The .txt file looks like this:

    3
    1 0 2 3
    5 6 7 4
    9 10 11 8
    13 14 15 12

    15 1 2 3
    14 13 12 11
    10 9 8 7
    6 0 5 4

    1 2 3 4
    5 6 0 8
    9 10 7 11
    13 14 15 12

    with the first integer being the number of puzzles and each block of 4 lines after that being a puzzle. The function looks like this:

    Code:
        int num_puzzles = 0;
        int i = 0;
        int j = 0;
    
        fscanf(fin, "%d", &num_puzzles);
    
        printf("There are %d puzzles\n", num_puzzles);
        
        for(i = 4; i < 8; i++)
        {
            for(j = 0; j < 4; j++)
            {
                fscanf(fin, "%d", &puzzle[i][j]);   
            }    
        }
      
            
    
        
        for(i = 4; i < 8; i++)
        {
            for(j = 0; j < 4; j++)
            {
                if(puzzle[i][j] == 0)
                {
                    printf("  _");
                }
                else
                {
                    printf("%3d", puzzle[i][j]);
                }
                
        
            }
            printf("\n");    
        }
    In this code I'm trying to read in the 2nd puzzle but it just won't work. It always reads in the first puzzle (or some strange behavior). I actually have to make the program select a random puzzle but I haven't gotten that far yet. Can someone help with the logic of this program?

  2. #2
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    Anyone? I've searched the forums already and found a similar problem but not the same. This shouldn't be all too complicated, it's just a 2D array of ints.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    Here let me post the whole program. Maybe there's a problem somewhere else? NOTE the program is just a scaffold at this point.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAX_FILE_LENGTH 30
    #define PUZZLE_SIDE 4
    #define EMPTY_SLOT 0
    
    void loadPuzzle(int puzzle[][PUZZLE_SIDE], FILE *fin);
    int getMove();
    void printPuzzle(int puzzle[][PUZZLE_SIDE]);
    int doMove(int puzzle[][PUZZLE_SIDE], int move);
    void swap(int *a, int *b);
    int solved(int puzzle[][PUZZLE_SIDE]);
    
    int main(void) 
    {
        int puzzle[PUZZLE_SIDE][PUZZLE_SIDE];
        char filename[MAX_FILE_LENGTH+1];
        int ans;
        FILE *fin;
        
        srand(time(NULL));
        
        printf("Welcome to the PUZZLE-15 game!\n");
        
        // Get the puzzle file.
        printf("Enter the file storing all of the puzzle configurations.\n");
        scanf("%s", filename);    
        
        while (ans != 2) {
            
            
            fin = fopen(filename, "r");
        
            // Load the puzzle.
            loadPuzzle(puzzle, fin);
           
            
            // Let's play!
            int move;
            
            printPuzzle(puzzle);
            move = getMove();
            
            // Keep on playing until the user gives up.
            while (move!=0) {
                  
                // Execute this move, seeing if it's okay.
                int okay = doMove(puzzle, move);
                
                // Print an error message for an invalid move.
                if (!okay) {
                    printf("Sorry, that is not a valid square to slide into ");
                    printf(" the open slot.\nNo move has been executed.\n");     
                }
                
                // Get out of the game for a winning move!
                else if (solved(puzzle))
                    break;
                
                // Go get the next move.
                printPuzzle(puzzle);
                move = getMove();
            }
            
            // Output an appropriate puzzle ending message.
            if (move != 0)
                printf("Great, you solved the puzzle!!!\n");
            else
                printf("Sorry, looks like you gave up on the puzzle.\n");
            
            // Get their next selection.
            printf("Which selection would you like?\n");
            printf("1. Load a new puzzle.\n");
            printf("2. Quit.\n");
            scanf("%d", &ans);
        
        }
        
    
        
    }
    
    // Pre-conditions: fin is pointed to the beginning of a file with a valid
    //                 file format for this problem.
    // Post-conditions: A random puzzle from the file pointed to by fin will be
    //                  stored in puzzle.
    void loadPuzzle(int puzzle[][PUZZLE_SIDE], FILE *fin) 
    {
        int num_puzzles = 0;
        int i = 0;
        int j = 0;
    
        fscanf(fin, "%d", &num_puzzles);
    
        printf("There are %d puzzles\n", num_puzzles);
        
        for(i = 4; i < 8; i++)
        {
            for(j = 0; j < 4; j++)
            {
                fscanf(fin, "%d", &puzzle[i][j]);   
            }    
        }
      
        for(i = 4; i < 8; i++)
        {
            for(j = 0; j < 4; j++)
            {
                if(puzzle[i][j] == 0)
                {
                    printf("  _");
                }
                else
                {
                    printf("%3d", puzzle[i][j]);
                }
            }
            printf("\n");    
        }
    }
    
    // Pre-conditions: none.
    // Post-conditions: A basic menu will be prompted and the user's result returned.
    int getMove() 
    {
        
    }
    
    // Pre-conditions: A valid puzzle is stored in puzzle.
    // Post-conditions: A depiction of the puzzle will be printed out.
    void printPuzzle(int puzzle[][PUZZLE_SIDE]) 
    {
    
    }
    
    // Pre-conditions: puzzle stores a valid puzzle configuration.
    // Post-conditions: If move is a valid square to slide into the open slot,
    //                  the move is executed and 1 is returned. Otherwise, 0
    //                  is returned and no change is made to puzzle.
    int doMove(int puzzle[][PUZZLE_SIDE], int move) 
    {
    
    }
    
    // Pre-condition: none
    // Post-condition: swaps the values in the variables pointed to by a and b.
    void swap(int *a, int *b) 
    {
        
    }
    
    // Pre-condition: puzzle stores a valid puzzle configuration.
    // Post-condition: Returns 1 if puzzles is solved, 0 otherwise.
    int solved(int puzzle[][PUZZLE_SIDE]) 
    {
        
    }

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    #define PUZZLE_SIDE 4
    ...
        int puzzle[PUZZLE_SIDE][PUZZLE_SIDE];
    ...
        for(i = 4; i < 8; i++)
        {
            for(j = 0; j < 4; j++)
            {
                fscanf(fin, "%d", &puzzle[i][j]);   
            }    
        }
    Values in the range of 4..7 are out of range for your array...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    That's what I was thinking, but Dev-C++ won't let me code it as int puzzle[][PUZZLE_SIDE];
    it says the array size is missing? I thought one could declare an array like this.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    No, you need to declare all dimensions of an array. No exceptions. When you pass it to a function, you can skip the first dimension, but when declaring it, the compiler needs to make the right amount of space for the array, so you need to tell the compiler how much space you want/need.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    Ok, I arbitrarily declared puzzles as int puzzles[200][PUZZLE_SIDE]; but still the same problem, it only reads/prints the first puzzle. I can't make it read any other puzzle.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    Is it something to do with the blank line in between puzzles?

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >> I can't make it read any other puzzle.

    You probably can...

    At a guess, loadPuzzle's first read instruction, the one that reads the number of puzzles, should only happen when you first read the file. If the user wants to play another game after his first one, a call to loadPuzzle puts part of the next puzzle in num_puzzle instead. Messes up what the array looks like.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    25

    Smile

    I see what you mean there. I moved the read-number-of-puzzles code to main, before the while loop for the game. I changed int puzzle[200][PUZZLE_SIDE]; to int puzzle[i][j]; and made necessary changes in all the functions. It's still somewhat broken but it'll load a different puzzle now Thanks citizen. Now to make it select a random one, that should be easier now

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    YES! I was just about to post my code again but I figured it out. I can now load/display random puzzles at will Muahahahaha. Still a long way to go on this prog but glad to be done with those first two functions.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    25
    Too quick to celebrate lol...I need a little bit of help. The program loads random puzzles...sort of. If I run the program it loads/displays the 1st puzzle, then the 2nd, then the 3rd, then random puzzles or sometimes an array of garbage if I keep telling it to load a new puzzle. I've got a number wrong somewhere or something out of order I think?

    Code:
    void loadPuzzle(int puzzle[][4], FILE* fin, int* puzzlenumber) 
    {
     
        int i;
        int j;
    
        for(i = *puzzlenumber; i < (*puzzlenumber + 4); i++)
        {
            for(j = 0; j < 4; j++)
            {
                fscanf(fin, "%d", &puzzle[i][j]);   
            }    
        }
    }
    There's the loadPuzzle function

    and here's the beginning of main

    Code:
    int main(void) 
    {
       
        char filename[MAX_FILE_LENGTH+1];
        int ans;
        FILE* fin;
        int puzzlenumber;
        int num_puzzles;
        
        printf("Welcome to the PUZZLE-15 game!\n");
        
        // Get the puzzle file.
        printf("Enter the file storing all of the puzzle configurations.\n");
        scanf("%s", filename);
    
        fin = fopen(filename, "r");
    
        fscanf(fin, "%d", &num_puzzles);
    
        printf("There are %d puzzles\n", num_puzzles);
    
        int i;
        int j;
    
        i = (num_puzzles * 5);
        j = PUZZLE_SIDE;
    
        int puzzle[i][j];
    
        srand(time(NULL));
    
        while (ans != 2) 
    {
            puzzlenumber = rand() % num_puzzles;
            puzzlenumber *= 5;
            
            // Load the puzzle.
            loadPuzzle(puzzle, fin, &puzzlenumber);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Read from file to an array
    By brooklyn1126 in forum C++ Programming
    Replies: 2
    Last Post: 05-15-2004, 08:32 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM