Thread: how to use two dimensional character array for reading fields from a file?

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    8

    Unhappy how to use two dimensional character array for reading fields from a file?

    Hi, New to C programming

    I am trying to write a program in C in which i will be changing the value of a particular field based on the input of the user. I understand that there is no way in C language where one can just simply change a line (or a portion of it) in a file. Rather the entire file has to be copied into another file and somewhere in the process of copying you can change the field.(Please comment on this if you think i am wrong) what i am trying to do is to read from a file(which has some records and each record has 4 fields). the data in the file is somehow like this(Numbers represent Gold,Silver and Bronze:
    USA: 47 72 33
    Canada: 55 21 33
    england: 55 40 71
    .......


    the format remains the same throughout the file. my program has to change any of those three numbers for a particular name(which will be provided by the user).
    users is asked to give 2 inputs: Name of the country, which is hold in "char country[5]", and 'a letter and a number' for identifying which field needs to be changed and by how much.
    following is the way i tried to code it but it wont work.

    Code:
    char countrya[50][200];
    int golda[200],bronzea[200],silvera[200],i,count=0;
    FILE *fpt1;
    char country[50],countrynew[50],input;
    
    
    // to count the number of lines in the file
    while(4==fscanf(fpt1,"%[^:]: %d %d %d\n", countrynew, &gold, &bronze, &silver))
      count++;
    
    // grap all the data into arrays.The problem is somewhat here as nothing is transfered to the arrays
    for (i=0;i<=count;i++)
    	  {
    	  fscanf(fpt1,"%[^:]: %d %d %d\n", countrya[i], golda[i], bronzea[i], silvera[i]);
    	  }
    
    // char country[50] holds the name provided by the user and then i tried to check and see which record holds that country so that i change the required field.
    for (i=0;i<=count;i++)
    	  {
    		  if (0==strcmp(countrya[i],country))
    		  {
                 if (input == 'g' || input == 'G')
    				 golda[i]= newgold;
    			 else if (input =='s' || input =='S')
    				 silvera[i] = newsilver;
    			 else if (input == 'b' || input == 'B')
    				 bronzea[i] == newbronze;
    			 else
    				 ;
    		  }
    	  }
    
    // now i tried to remove the file and create a new one and put the data hold in the arrays in that one.
    
     fclose(fpt1);
    	  remove(fpt1);
    	  fpt1=fopen(filename,"a");
    	  for (i = 0 ; i <= count ; i++)
    	  {
    		  fprintf(fpt1,"%s: %d %d %d\n",countrya[i],golda[i],bronzea[i],silvera[i]);
    		
    	  }
    	  fclose(fpt1);
    I get Tons of I's on the screen when i run this program in VS2008 , and
    : 0 0 0
    : 0 0 0
    .......

    when i run it using the linux cc compiler. Please help,

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    There's no need to count the number of countries in the file, as you don't do anything with it. So you might as well use that original 4==fscanf loop to put things in the arrays proper, rather than into temporary variables that get overwritten.

    And files are more like sheets of paper than mobius strips; once you get to the bottom, you don't automatically go back up to the top. If you want to reread a file, you'll have to call rewind or fseek to get back to the beginning of the file.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    8
    Quote Originally Posted by tabstop View Post
    There's no need to count the number of countries in the file, as you don't do anything with it. So you might as well use that original 4==fscanf loop to put things in the arrays proper, rather than into temporary variables that get overwritten.

    And files are more like sheets of paper than mobius strips; once you get to the bottom, you don't automatically go back up to the top. If you want to reread a file, you'll have to call rewind or fseek to get back to the beginning of the file.
    I understand what you say, but the problem is that i can not get the values of fscanf into the arrays, as i mentioned. have i made any mistake there?

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You got the ampersands right everywhere else....

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by atif7865 View Post
    Code:
    char countrya[50][200];
    Do you want 50 countries with 200 max characters for the country's name or vice-versa?
    Quote Originally Posted by atif7865 View Post
    // to count the number of lines in the file
    while(4==fscanf(fpt1,"%[^:]: %d %d %d\n", countrynew, &gold, &bronze, &silver))
    count++;
    Why do you need to count the number of lines in the file; any reason for that?
    Quote Originally Posted by atif7865 View Post
    Code:
    // grap all the data into arrays.The problem is somewhat here as nothing is transfered to the arrays
    for (i=0;i<=count;i++)
    	  {
    	  fscanf(fpt1,"%[^:]: %d %d %d\n", countrya[i], golda[i], bronzea[i], silvera[i]);
             }
    You need a pointer to the location where the medals tally is going to be stored instead of the actual location itself ie &golda[i], &bronzea[i], &silvera[i].
    Increment countrya[i] before reading the next line else it'll overwrite the value stored there previously.

  6. #6
    Registered User
    Join Date
    Nov 2008
    Posts
    8
    Quote Originally Posted by itCbitC View Post
    Do you want 50 countries with 200 max characters for the country's name or vice-versa?

    Why do you need to count the number of lines in the file; any reason for that?

    You need a pointer to the location where the medals tally is going to be stored instead of the actual location itself ie &golda[i], &bronzea[i], &silvera[i].
    Increment countrya[i] before reading the next line else it'll overwrite the value stored there previously.
    first of all, thank you for your response.
    well i need 200 countries with 50 characters max.

    yes, i think i can get rid of counting the number of the lines.

    as far as you last response, i just tried using ampersand too, it still isnt working. Am I using the two dimensional array of countrya in the fscanf rightly??

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    8
    Quote Originally Posted by tabstop View Post
    You got the ampersands right everywhere else....
    hi, thanks for reply,,

    i have modified the code a bit but am getting an error.




    Code:
    char ch;
    	char country[50],countrynew[50],input;
    	int gold,bronze,silver,count=0,newgold,newbronze,newsilver,newcount,i;
    	 char countrya[200][50];
      int golda[200],bronzea[200],silvera[200];
    	FILE *fpt1;
    
    while(4==fscanf(fpt1,"%[^:]: %d %d %d\n", &countrynew, &gold, &bronze, &silver))
    	  {
    	  countrya[i] = countrynew;
    	  golda[i] = gold;
    	  bronzea[i] = bronze;
    	  silvera[i] = silver;
    	  i++;
    	  }
    .........
    where is the problem in this code?

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    You don't need that many variables though that won't give you an error since your main problem still remains; shown in red below.
    Quote Originally Posted by atif7865 View Post
    Code:
    char ch;
    	char country[50],countrynew[50],input;
    	int gold,bronze,silver,count=0,newgold,newbronze,newsilver,newcount,i;
    	 char countrya[200][50];
      int golda[200],bronzea[200],silvera[200];
    	FILE *fpt1;
    
    while(4==fscanf(fpt1,"%[^:]: %d %d %d\n", &countrynew, &gold, &bronze, &silver))
    	  {
    	  countrya[i] = countrynew;
    	  golda[i] = gold;
    	  bronzea[i] = bronze;
    	  silvera[i] = silver;
    	  i++;
    	  }
    .........
    where is the problem in this code?
    Replace the fscanf() line with something like
    Code:
    fscanf(fpt1,"%[^:]: %d %d %d\n", &countrya[i][0], &golda[i], &bronzea[i], &silvera[i])

  9. #9
    Registered User
    Join Date
    Sep 2008
    Posts
    5
    Quote Originally Posted by atif7865 View Post
    hi, thanks for reply,,

    i have modified the code a bit but am getting an error.




    Code:
    char ch;
    	char country[50],countrynew[50],input;
    	int gold,bronze,silver,count=0,newgold,newbronze,newsilver,newcount,i;
    	 char countrya[200][50];
      int golda[200],bronzea[200],silvera[200];
    	FILE *fpt1;
    
    while(4==fscanf(fpt1,"%[^:]: %d %d %d\n", &countrynew, &gold, &bronze, &silver))
    	  {
    	  countrya[i] = countrynew;
    	  golda[i] = gold;
    	  bronzea[i] = bronze;
    	  silvera[i] = silver;
    	  i++;
    	  }
    .........
    where is the problem in this code?
    a better code would be

    Code:
    typedef struct{
         char    country_name[50];
         int       gold;
         int       silver;
         int       bronze;
    } SPORTS;
    
    SPORTS Sports1[200] = {0};
    FILE *pFile1;
    int a_pos = 0;
    
    while ( fscanf( pFile1, "%[^:]: %d %d %d\n", Sports1[a_pos].country_name,
                                      &Sports1[a_pos].gold, &Sports1[a_pos].bronze,
                                      &Sports1[a_pos].silver ) != EOF ) {
          ++a_pos;
    }
    You don't need to use so many variables to temporary store them, in fact you can actually copy them directly to your main variable. I used a structure array instead because it is much more manageable. And yeah, it is always needed to put an ampersand before every variable that you want to copy the data into because basically fscanf takes the data out of the FILE and then stores it in the memory location containing the variable that you want to store, so to do that it needs the address of the variable therefore you need to use the ampersand operator. But this does not apply to strings/array of chars simply because the name of the array itself is the address to the first element in the array. Oh, I don't know why you use fscanf == 4, perhaps to check whether you have scanned all the data, a better method i believe would be != EOF. Hope this helps.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Oh, I don't know why you use fscanf == 4, perhaps to check whether you have scanned all the data, a better method i believe would be != EOF.
    Except that 4 is a positive assertion of success, not a negative assertion of complete failure.

    With a badly formatted input file, if fscanf gets stuck at the first conversion, it will enter an infinite loop of always returning 0. Never making progress, and never (eventually) reaching EOF.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multi dimensional array
    By $l4xklynx in forum C Programming
    Replies: 7
    Last Post: 01-03-2009, 03:56 AM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM

Tags for this Thread