Thread: 2Dimensional arrays..read from txt file PROBLEM! :O

  1. #1
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53

    Exclamation 2Dimensional arrays..read from txt file PROBLEM! :O

    Hey everyone, so I have this following code, and what I'm supposed to do is this (assignment copied and pasted below):

    Code:
    The following table shows the total sales for salespeople of the ABC Manufacturing Company.
            Salesperson      Week 1  Week 2 Week 3  Week 4
        ===============  ======  ======  ======  ======
        Nguyen, Michael    25     30      45      20
        Johnson, Mary      32     30      33      29
           ...                    
    The price of the product being sold is $1985.95 (define it as a constant). Write a program that permits the input of the data, up to 25 salespersons and up to 6 weeks, prints a replica of the original table to the screen, and writes to a file a table showing the dollar value of sales for each individual during each week along with his or her total sales. Also it prints the total sales, the lowest and the highest value for each week, and the total sales for the company.
    Code:
    #include <stdio.h>
    
    #define MAX_ROWS 25
    #define MAX_COLS 20
    
    int main()
    
    {
    
    
       FILE *fp = fopen("names.txt", "r");
       char array[25][20] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
       if ( fp )
       {
          for ( ;; )
          {
             int c = getc(fp);
             if ( c == EOF )
             {
                break;
             }
             if ( c != '\n' && c != '\r' )
             {
                array[i][j] = c;
                if ( ++j >= col )
                {
                   j = 0;
                   if ( ++i >= row )
                   {
                      break;
                   }
                }
             }
          }
          fclose(fp);
       }
    
    
    
       for ( i = 0; i < row; i++ )
       {
          for ( j = 0; j < col; j++ )
          {
             putchar(array[i][j]);
          }
          putchar('\n');
       }
    
    
    
       return 0;
    }
    so what i've got so far is the names txt. file being inputted and read. Here are the contents of the names.txt file:

    Code:
    16
    Kelly, Victor       
    Lam, Gary           
    Nagasake, David     
    Nguyen, Jeff        
    Nguyen, Michael     
    Sinn, Scott         
    Smith, Jacob        
    Son, Thai           
    Tavares, Maribel    
    Tran, Diane         
    Tsukamoto, Andrew   
    Wang, Mary          
    Young, Daniel       
    Wells, Steve        
    Wong, Justin        
    Johnson, Mary
    I have two questions.

    1) How do I skip the first line of the table, in this case, the number 16 at the very top? that number just indicates the number of people there are..I'm supposed to delete that and it's not supposed to be read even thought it's in the txt file. So how do i skip that line?

    2) How do I read in 2 .txt files at the same time? When i read in the 2 txt files (names.txt and sales.txt) the output should look like in the assignment above.




    see how the two tables are nicely alligned? the names.txt
    is on the left and the sales.txt is on the right?
    How do i input both files like that and make them alligned to
    each other?

    btw, the sales.txt file contents are:
    Code:
    4
    25 20 25 25
    20 22 23 22
    25 26 25 22
    30 28 25 26
    25 30 45 20
    30 25 20 21
    27 25 24 26
    20 23 24 20
    28 26 24 25
    30 10 35 32
    28 29 30 35
    15 16 15 14
    12 15 12 19
    20 24 20 18
    10 15 12 16
    32 30 33 29
    Thanks everyone!!!
    Last edited by kal123456; 01-30-2013 at 02:34 PM.

  2. #2
    Registered User
    Join Date
    Jan 2013
    Posts
    5
    regarding the first question, it's easier to work with fgets function, it reads entire line instead of reading character by character. it will save you time and headache, in my opinion. in the example below, i used 'mem', a pointer to a heap memory address, to store the line, but you can use an array of chars (just don't forget the '&' sign when using the fgets). now you can check if the ascii value of the first character in the line represents a number.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    #define MAX_ROWS 25
    #define MAX_COLS 20
    #define MAX_SIZE 200
    
    int main()
    {
       FILE *fp = fopen("names.txt", "r");
       char *mem = (char *)malloc(sizeof(char) * MAX_SIZE);
       if ( fp ) {
          while (fgets(mem, MAX_SIZE, fp)) {
            if (isdigit(mem[0])) continue; //ignore first row
            ...
          }
          free(mem);
          fclose(fp);
       }
       ...
       return 0;
    }
    Last edited by zw_hat; 01-30-2013 at 02:59 PM.

  3. #3
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    @zw_hat Thanks for the great code!! I think i might use fgets then, it's probably easier haha! btw, in line 35 of your code, what are the ... ?

  4. #4
    Registered User
    Join Date
    Jan 2013
    Posts
    5
    haa not much.. it's just the rest of the implementation (copying mem to your array[i] and etc). if you're not sure, i can give more details.

    cheers.

  5. #5
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    yeah could you please give more details? thanks!!

  6. #6
    Registered User
    Join Date
    Jan 2013
    Posts
    5
    Code:
    #include <stdio.h>
     #include <ctype.h>
     #define MAX_ROWS 25
     #define MAX_COLS 20 
    #define MAX_SIZE 200
     
    int main() {
       char array[25][20] = {0};
        int i = 0;
        int j = 0;
        int row = 25;
        int col = 20;
        FILE *fp = fopen("names.txt", "r");
        char *mem = (char *)malloc(sizeof(char) * MAX_SIZE);
        if ( fp ) {
           while (fgets(mem, MAX_SIZE, fp)) {
             if (isdigit(mem[0])) continue; /*ignore first row*/
             /* so in case it is not the first row
               we will have to store it in the array.
               using strncpy to copy from `mem` to `array[j]`
             */
             if (j >= MAX_ROWS) break;
             strncpy(array[j], mem, MAX_COLS);
             array[j][strlen(mem)-1]='\0'; /*add null termination*/
             j++;
           }
           free(mem);
           fclose(fp);
        }
        ...
        return 0;
     }
    the second '...' is just copy-paste from where i stopped in your code. so, what i did above was using strncpy to copy what i got in `mem` into the `array` (see how short it is).
    i haven't compiled it nor run it, but it seems fine.

    is that clear or you've wanted different details?
    Last edited by zw_hat; 01-30-2013 at 03:55 PM.

  7. #7
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    ok so i'm trying to make a separate function that will read from a txt file into a 2D array...somehow it's not working it keeps on saying that "filename" is undeclared....help please, thanks!!

    Code:
    #include <stdio.h>
    
    #define INPUT_FILE_GET_NAMES "names.txt"
    #define INPUT_FILE_GET_SALES "sales.txt"
    #define MAX_ROWS_NAMES 25
    #define MAX_COLS_NAMES 20
    #define MAX_ROWS_SALES 25
    #define MAX_COLS_SALES 6
    
    //Function Declarations
    char getNames(char namesArray[][MAX_COLS_NAMES], char filename[]);
    
    
    
    int main()
    
    {
    
    //Local Declarations
    
       char namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
       getNames (namesArray, filename);
    
       return 0;
    }
    
    char getNames(char namesArray[][MAX_COLS_NAMES], char filename[])
    {
        //Statements
    FILE *fp = fopen("names.txt", "r");
    int i, j;
    int col=20;
    int row=25;
    if ( fp )
       {
          for ( ;; )
          {
             int c = getc(fp);
             if ( c == EOF )
             {
                break;
             }
             if ( c != '\n' && c != '\r' )
             {
                namesArray[i][j] = c;
                if ( ++j >= col )
                {
                   j = 0;
                   if ( ++i >= row )
                   {
                      break;
                   }
                }
             }
          }
          fclose(fp);
       }
    
    
    
       for ( i = 0; i < row; i++ )
       {
          for ( j = 0; j < col; j++ )
          {
             putchar(namesArray[i][j]);
          }
          putchar('\n');
       }
    
    
    
    
    
    }

  8. #8
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    I just removed the second parameter from the getNames function, now my code looks like this and it will run and then crash....PLEASE HELP!!

    Code:
    #include <stdio.h>
    
    #define INPUT_FILE_GET_NAMES "names.txt"
    #define INPUT_FILE_GET_SALES "sales.txt"
    #define MAX_ROWS_NAMES 25
    #define MAX_COLS_NAMES 20
    #define MAX_ROWS_SALES 25
    #define MAX_COLS_SALES 6
    
    //Function Declarations
    char getNames(char namesArray[][MAX_COLS_NAMES]);
    
    
    
    int main()
    
    {
    
    //Local Declarations
    
       char namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
      //Statements
       getNames (namesArray);
    
       return 0;
    }
    
    char getNames(char namesArray[][MAX_COLS_NAMES])
    {
        //Statements
    FILE *fp = fopen("names.txt", "r");
    int i, j;
    int col=20;
    int row=25;
    if ( fp )
       {
          for ( ;; )
          {
             int c = getc(fp);
             if ( c == EOF )
             {
                break;
             }
             if ( c != '\n' && c != '\r' )
             {
                namesArray[i][j] = c;
                if ( ++j >= col )
                {
                   j = 0;
                   if ( ++i >= row )
                   {
                      break;
                   }
                }
             }
          }
          fclose(fp);
       }
    
    
    
       for ( i = 0; i < row; i++ )
       {
          for ( j = 0; j < col; j++ )
          {
             putchar(namesArray[i][j]);
          }
          putchar('\n');
       }
    
    
    
    
    
    }

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Posting the actual error message with line numbers (i.e. copy-paste from your terminal/compiler/IDE) would be very helpful. Please do so in the future.

    Take a look at line 27:
    Code:
    getNames (namesArray, filename);
    That is in the main function. Where in the main function is there a variable called filename? There isn't. What you probably meant to do was pass in your defined constant:
    Code:
    getNames (namesArray, INPUT_FILE_GET_NAMES);
    Then, in the getNames function, you must change your call to fopen to use the filename you passed in.

    Note, you haven't (yet) implemented the proper error handling for fopen I mentioned in your other thread. I would do something like (pseudo-code, don't copy this verbatim):
    Code:
    // note, there is no reason to return a char
    // I'm having it return an int, which is a more common return type for error codes
    int getNames(char namesArray[][MAX_COLS_NAMES], char filename[]) {
        ..
        fp = fopen(...);
        if (fp == NULL) {  // fopen failed
            perror("fopen");  // print a meaningful error message
            return -1;  // common return code for error, leave the function immediately
        }
        // fp is not null, fopen succeeded, carry on with your function
        ...
        return 0;  // common return code for success
    }

  10. #10
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    OMG thanks so much for clearing that out! and actually, I changed up the parameters a bit, so now there's only one parameter, and I changed the way I open my file, similar to the pseudocode you provided. Somehow, the program runs and then it says "homework1.exe stopped working" and basically it crashed...why?!

    Code:
    #include <stdio.h>
    
    #define INPUT_FILE_GET_NAMES "names.txt"
    #define INPUT_FILE_GET_SALES "sales.txt"
    #define MAX_ROWS_NAMES 25
    #define MAX_COLS_NAMES 20
    #define MAX_ROWS_SALES 25
    #define MAX_COLS_SALES 6
    
    //Function Declarations
    int getNames(char namesArray[][MAX_COLS_NAMES]);
    
    
    
    int main()
    
    {
    
    //Local Declarations
    
       int namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
      //Statements
       getNames (namesArray);
    
       return 0;
    }
    
    int getNames(char namesArray[][MAX_COLS_NAMES])
    {
        //Statements
    FILE *fp;
    int i, j;
    int col=20;
    int row=25;
    
    //open the sequential access file
     fp = fopen(INPUT_FILE_GET_NAMES,"r");
    
    for(i=0;i<row;i++)  {
         for(j = 0; j < col; j++)
         {
             fscanf(fp,"%d\n", namesArray[i][j]);
         }
     }
    
    
    fclose(fp);
    
    return 0;
    
    
    
    }

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You never check of fopen succeeded. If fp is NULL, you need to exit the getNames function before you do anything else. Otherwise, fscanf is trying to use fp, which is NULL, and it can't access the members of fp.

    It makes sense that getNames would only use the names file. But it would also be silly if you wrote a getSales function, that behaved exactly like getNames, except for opened a different file. That's a bunch of repeated code, meaning twice the chance you make a mistake, twice the code to debug and maintain. If you are doing the same process for reading names and sales files, a better solution would be to go back to taking a filename as a parameter to your function:
    Code:
    int main(void)
    {
        int namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
        int salesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
    
        getFile(namesArray, INPUT_FILE_GET_NAMES);
        getFile(namesArray, INPUT_FILE_GET_SALES);
        ...
    That way you have one function that can be reused multiple times. That's one function to debug and maintain instead of two, which is just plain good design.

  12. #12
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    Ohh ok! I don't think I'm gonna make one function do the same 2 things, cause my teacher prefers us to write 2 separate functions, but thanks for letting me know, i'll use it in the future! so I just fixed that part and added the NULL part, but the program still crashes!!! what am i doing wrong?

    Code:
    #include <stdio.h>
    
    #define INPUT_FILE_GET_NAMES "names.txt"
    #define INPUT_FILE_GET_SALES "sales.txt"
    #define MAX_ROWS_NAMES 25
    #define MAX_COLS_NAMES 20
    #define MAX_ROWS_SALES 25
    #define MAX_COLS_SALES 6
    
    //Function Declarations
    int getNames(char namesArray[][MAX_COLS_NAMES]);
    
    
    
    int main()
    
    {
    
    //Local Declarations
    
       int namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
      //Statements
       getNames (namesArray);
    
       return 0;
    }
    
    int getNames(char namesArray[][MAX_COLS_NAMES])
    {
        //Statements
    FILE *fp;
    int i, j;
    int col=20;
    int row=25;
    
    //open the sequential access file
     fp = fopen(INPUT_FILE_GET_NAMES,"r");
     if(fp == NULL)
            {
                printf("Error, can't open '%s' file!!!\n", namesArray[1]);
                return -1;
            }
    for(i=0;i<row;i++)  {
         for(j = 0; j < col; j++)
         {
             fscanf(fp,"%d\n", namesArray[i][j]);
         }
    
     }
    
    
    fclose(fp);
    
    return 0;
    
    
    
    }

  13. #13
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    ok now i get it to print something, but instead of printing out the contents of the txt file, it just prints:
    Code:
    0000000000000000000000000
    Process returned 0 (0x0)   execution time : 0.055 s
    Press any key to continue.
    what am i doing wrong?!?!

    Code:
    #include <stdio.h>
    
    #define INPUT_FILE_GET_NAMES "names.txt"
    #define INPUT_FILE_GET_SALES "sales.txt"
    #define MAX_ROWS_NAMES 25
    #define MAX_COLS_NAMES 20
    #define MAX_ROWS_SALES 25
    #define MAX_COLS_SALES 6
    
    //Function Declarations
    int getNames(char namesArray[][MAX_COLS_NAMES]);
    
    
    
    int main()
    
    {
    
    //Local Declarations
    
       int namesArray[MAX_ROWS_NAMES][MAX_COLS_NAMES] = {0};
       int i = 0;
       int j = 0;
       int row = 25;
       int col = 20;
    
      //Statements
       getNames (namesArray);
    
       return 0;
    }
    
    int getNames(char namesArray[][MAX_COLS_NAMES])
    {
        //Statements
    FILE *fp;
    int i, j;
    int col=20;
    int row=25;
    
    //open the sequential access file
     fp = fopen(INPUT_FILE_GET_NAMES,"r");
     if(fp == NULL)
            {
                printf("Error, can't open file!!!\n");
                exit(101);
            }
    else{
    
    
    
    for(i=0;i<row;i++)  {
         for(j = 0; j < col; j++)
         {
             fscanf(fp,"%d\n", &namesArray[i][j]);
         }
    printf("%d", namesArray[i][j]);
     }
    }
    
    fclose(fp);
    
    return 0;
    
    
    
    }

  14. #14
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    If your name file contains characters, why are you trying to read integers?
    Code:
    for(i=0;i<row;i++)  {
         for(j = 0; j < col; j++)
         {
             fscanf(fp,"%d\n", &namesArray[i][j]);
         }
    printf("%d", namesArray[i][j]);
     }
    }

  15. #15
    Registered User
    Join Date
    Jan 2013
    Location
    San Jose, CA
    Posts
    53
    Ohhh, so then how do i change it to read characters?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. read data from file into 2 dimensional arrays help
    By khoavo123 in forum C Programming
    Replies: 4
    Last Post: 02-02-2012, 02:30 AM
  2. Reading Picture file into 2dimensional data array?
    By DiscoStu9 in forum C Programming
    Replies: 10
    Last Post: 08-25-2009, 06:03 PM
  3. passing 2dimensional arrays to functions
    By owi_just in forum C Programming
    Replies: 1
    Last Post: 04-25-2005, 08:08 AM
  4. Replies: 4
    Last Post: 01-30-2005, 04:50 AM

Tags for this Thread