Thread: Reading in data from Text file

  1. #106
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    There are a few things wrong with that.

    First of all, your file consists of strings (names) as well as numbers, does it not? What do you think will happen when fscanf() is told to find a number and it sees a string? It returns without reading the string and without setting its numerical argument to anything. In other words, if this happened, table[a][b] would not be initialized, which is exactly what looks like is happening.

    What can you do about this? Well, you can see if it's happening with this:
    Code:
    if(fscanf(file, "%d ", &table[a][b]) != 1) {
        printf("Error reading table[%d][%d]\n", a, b);
    }
    And you can "fix" it with this:
    Code:
    while(fscanf(file, "%d ", &table[a][b]) != 1) {
        int c;
        do {
            c = getc(file);
        } while(c != '\n');
    }
    (Note that that doesn't handle EOF, but it's good enough for now.)

    When fscanf() encounters something it didn't like, that code removes any characters up until a newline and then tries the fscanf() call again.

    Of course, that doesn't fix the real problem: you're probably interested in the names, after all. So instead of just discarding them, why don't you have another look at the code that I threw at you?
    Code:
    int x, y;
    
    for(y = 0; y < 10; y ++) {
        fscanf(fp, "%s", cityname[y]);
    }
    
    for(y = 0; y < 10; y ++) {
        fscanf(fp, "%s", unusedname);
        for(x = 0; x < 10; x ++) {
            fscanf(fp, "%i", &chart[y][x]);
        }
    }
    Your input file consists of ten names, followed by ten lines with a name and ten numbers on them. That's exactly what this code reads. It discards the name on the last ten lines, because that same information can be obtained from the first line.

    Please, examine that and tell me what you don't understand about it . . . .

    Also -- I think your loops are looping too often.
    Code:
           for (a=0; a <= col;a++)
            {
              for (b=0; b <= row;b++)
    Most of the time, you'll want < instead of <= in loops like those.
    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.

  2. #107
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    does the table you fill and table you print member later is the same array?

    or these parts of the code are in different functions?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #108
    Registered User
    Join Date
    Mar 2008
    Posts
    7
    Here's the code at the moment:

    Code:
    #include <stdio.h> 
    #include <math.h>
    #define col 9
    #define row 9
    
    // Menu
    char menu(void); 
    
    int main(void) 
    { 
      // file opening stuff  
     FILE *file;
     int a = 0, b = 0;
     int table[a][b];
     file = fopen("numbers2.txt", "r");   
    
      char option,rtn; 
      int i, j;
      int Distance = 0;
      double Cost = 0.0;
    
      option = menu(); 
      while(option != '5') 
      { 
       switch(option) 
       {       
          case '1':  
    {
                    // works out distance between 2 points the user enters
                    printf("Enter 2 Numbers: ");
                    scanf("&#37;d%c", &a, &rtn);
                    scanf("%d%c", &b, &rtn);
                    Distance = (table[a][b]);
                    printf("%-4d", table[a][b]);
                    printf(" Miles");
                    printf("\n");
    }
    		   break; 
    		   
    	case '2' :
     {        
                    // calculates cost of journey
                    Cost = (Distance * 0.40);
                    printf("Cost: &#163;");
                    printf("%2.2f", Cost);
                    printf("\n");
    }
             break;	   
    		   
    		   
    	  case '3':
    {
        
    if(file != NULL) // file exists
      {
        
        printf("File opened successfully.\n");
          
           for (a=0; a <= col;a++)
            {
              for (b=0; b <= row;b++)
               {
               fscanf(file, "%d ", &table[a][b]);
                
    
                printf("%-4d ", table[a][b]);
               }
               printf("\n");
               
             }
           
          fclose(file);
                            
      }
        else // file doesn't exist
     {
      printf("Error: can't open file\n");
     }
    }             
    		   break; 
    		   
    		      case '4':  
    {
    
                    printf("%-4d", table[10][3]);
    
    }
    		   break; 
                         
      default: 
               
       printf("\n-----------------------------\n"); 
       printf("Invalid choice.\n");
       printf("-----------------------------\n"); 
     
         } 
        option = menu(); 
      } 
    }    
    
            char menu(void) 
    { 
            
    // Print Main Menu   
            
       char option,rtn; 
       printf("\n------------------------------\n"); 
       printf("            Menu                 "); 
       printf("\n------------------------------\n"); 
       printf("1 - Enter 2 Points\n"); 
       printf("2 - Calculate Cost of Journey\n"); 
       printf("3 - Display Table\n"); 
       printf("4 - Test\n");
       printf("5 - Quit");
       printf("\n------------------------------\n"); 
       printf("Please enter your choice: "); 
       printf("\n------------------------------\n"); 
       scanf("%c%c",&option,&rtn); 
       return option; 
    }
    numbers2.txt (NOTE: im not using the place names at the moment, but I will get on to that after I have got this to work)
    Code:
    0 23 12 89 456 123 46 732 345 123
    23 0 46 234 123 46 89 234 567 90
    12 46 0 767 456 46 234 123 732 35
    89 234 767 0 732 32 48 67 98 100
    456 123 456 732 0 234 46 89 89 732
    123 46 46 32 234 0 123 46 123 234
    46 89 234 48 46 123 0 46 89 19
    732 234 123 67 89 46 46 0 123 732
    345 567 732 98 89 123 89 123 0 78
    123 90 35 100 732 234 19 732 78 0
    the number for A doesn't work, it just ignores the number input for A
    Input for b works, it goes to the right number, but on the last line :s

    [CODE]
    ------------------------------
    Please enter your choice:
    ------------------------------
    1
    Enter 2 Numbers: 4
    3
    98 Miles

    ------------------------------
    [CODE]
    The first number isn't being counted, but the 2nd one is :s.

    Any help please

  4. #109
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    int a = 0, b = 0;
    int table[a][b];
    so you define table of zero size, how do you plan to read something into it? Make some room buddy!!
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #110
    Registered User
    Join Date
    Mar 2008
    Posts
    7
    Ok, right I think I might have got this working, I changed the 0's to 9's. When I go to the option to enter in 2 numbers I get

    Code:
    ------------------------------
    Please enter your choice:
    ------------------------------
    1
    Enter 2 Numbers: 1
    1
    1160589875 Miles
    But, if I enter 3 at the menu to bring up the table, and then it goes back to the menu and I choose the enter 2 numbers option again, it's correct:

    Code:
    ------------------------------
    Please enter your choice:
    ------------------------------
    1
    Enter 2 Numbers: 1
    1
    0    Miles
    
    ------------------------------
    So I guess that I should have the program load both the table and the menu.
    But I just want the table to show once under the menu. Then when I go back to the main menu for the other options it won't show the table anymore, but it will still be loaded, if that makes any sense :S

  6. #111
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    printf("&#37;-4d", table[10][3]); - what does this suppose to do?

    you already have a code the correctly scans all the table - use it
    Code:
    for (a=0; a <= col;a++)
    {
    	for (b=0; b <= row;b++)
    	{
    		printf("%-4d ", table[a][b]);
    	}
    	printf("\n");
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #112
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    death yea thats how the first program was i have data.txt
    Code:
    -	London	Bath	Cardiff	Carlisle	Durham	Exeter	Leeds	Norwich	Truro	York
    London	0	23	12	89	456	123	46	732	345	123
    Bath	23	0	46	234	123	46	89	234	567	90
    Cardiff	12	46	0	767	456	46	234	123	732	35
    Carlisle	89	234	767	0	732	32	48	67	98	100
    Durham	456	123	456	732	0	234	46	89	89	732
    Exeter	123	46	46	32	234	0	123	46	123	234
    Leeds	46	89	234	48	46	123	0	46	89	19
    Norwich	732	234	123	67	89	46	46	0	123	732
    Truro	345	567	732	98	89	123	89	123	0	78
    York	123	90	35	100	732	234	19	732	78	0
    i want to extract all the numbers from it into an array without having it statically set like this:
    Code:
    int chart [10][10] = { // Array for the Table and Plot points
       {0,23,12,89,456,123,46,732,345,123},
       {23,0,46,234,123,46,89,234,567,90},
       {12,46,0,767,456,46,234,123,732,35},
       {89,234,767,0,732,32,48,67,98,100},
       {456,123,456,732,0,234,46,89,89,732},
       {123,46,46,32,234,0,123,46,123,234},
       {46,89,234,48,46,123,0,46,89,19},
       {732,234,123,67,89,46,46,0,123,732},
       {345,567,732,98,89,123,89,123,0,78},
       {123,90,35,100,732,234,19,732,78}
        };
    i want to take that same above data from the text file without the place names and the -

  8. #113
    Registered User
    Join Date
    Mar 2008
    Posts
    147

    right

    right after quite a bit of reading and playing i have got it however i have got a out put issue which i dont under stand.

    this is my text file data.txt
    Code:
    -	London	Glasgow	Birmingham	Manchester	Luton	Derby	Bournemouth	Stafford	Stoke	Cardiff																																																																																									
    0	403	118	209	34	129	108	141	158	151	403	0	209	217	371	285	455	263	249	398	118	209	0	96	86	46	170	28	44	124	209	217	96	0	176	90	261	68	54	203	34	371	86	176	0	97	122	109	126	166	129	285	46	90	97	0	199	34	36	162	108	455	170	261	122	199	0	194	210	164	141	263	28	68	109	34	194	0	16	137	158	249	44	54	126	36	210	16	0	153	151	398	124	203	166	162	164	137	153	0
    notice ive changed the data all the distances are correct

    right this is my test program to read in from a text file and outputto scree:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void readin(char towns[11][11], int dist[10][10]);
    void display(char towns[11][11], int dist[10][10]);
    
    int main (void)
    {
        char towns[11][11];
        int dist[10][10];
        int choice;
        readin(towns,dist);
        display(towns,dist);
        printf("continue?");
        scanf("%d",&choice); 
    }
    
    
    
    
    
    
    void readin(char towns[11][11], int dist[10][10])
    {
        int i, j;
     	char filename[21], p1, p2;
    	FILE *in_file;
    
    	printf("\nEnter the name of the input file, name must be 20 charecters or less: ");
    	scanf("%s", &filename);
    	
    	//open the file and read from it
    
    	
    	in_file = fopen(filename,"r");
    
    	if (in_file == NULL)
    	{
    		printf("\nCannot open %s\n", &filename);
    	}
        else if (in_file != NULL)
        {
    	for(i=0;i<11;i++)
    	{
    		fscanf(in_file, "%s ", &towns[i]);
    	}
    
    	for(i=0;i<10;i++)
    	{
    		for(j=0;j<10;j++)
    		{		
    			fscanf(in_file, "%d ", &dist[i][j]);
    		}
    	}
    }
    
    }
    
    void display(char towns[11][11], int dist[10][10])
    {
            int row, col;
            printf("\n------------------------------------------Distance Chart--------------------------------------------------\n"); 
            
             for (row=0; row<11;row++) 
            {
                printf("%-14s",towns[row]);
            }
            printf("\n");
            for (row=0; row<10;row++) 
            {
                printf("%-14s",towns[row+1]);
                
                    for (col=0;col<10;col++)
                    printf("%-14d", dist[row][col]);
                    printf("\n");
            }      
            printf("\n----------------------------------------------------------------------------------------------------------\n");
    }

    everything seems to be ok but when i go to run it i get this output:

    http://i57.photobucket.com/albums/g2...k/output-1.jpg


    i dont see more than 1 stafford in my txt file why is this happening and how can i fix it

  9. #114
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    probably due to a buffer overrun. You only allow the storage of 11 characters for each town name, but Bournemouth requries 12. 11 plus a null character.

    Since there is no null stored at the end of Bournemouth, when you print it, it prints until a null is encountered.
    Last edited by spydoor; 04-02-2008 at 11:07 AM.

  10. #115
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Oh my goodness!
    Don't read strings with scanf in such a unsafe way.
    Have a read: http://cpwiki.sf.net/Buffer_overruns
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #116
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    ive fixed it a place name was tooo long so i changed it

  12. #117
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Fix your scanf and fscanf. Read the article I linked to.
    Great article and it really shows the horrors of buffer overruns (which is exactly what your code is prone to!).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #118
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    Quote Originally Posted by Elysia View Post
    Fix your scanf and fscanf. Read the article I linked to.
    Great article and it really shows the horrors of buffer overruns (which is exactly what your code is prone to!).
    gonna fix that when my program is fabb




    new problem

    i have this code i want it to recognise when i have enterd a incorrect place name

    Code:
    const char *cities[] = {"London", "Glasgow", "Birmingham",	"Manchester", "Luton", "Poole", "Stafford", "Stoke", "Cardiff", "Derby"};
    
         else if(numstops>0)
                   {
                    
                      for(i=0;i<numstops;i++) //loops round depeneding on how many stops was enterd
                      {
                        if(wrong !=1)
                        {                     
                         printf("\n Please enter the name for Stop %-1d: ",i+1);
                         }
                       wrong=0;  
                       scanf("%16s",stopname[i]);
                              size_t x;
                              for(x = 0; x < sizeof(cities) / sizeof(*cities); x ++)
                               {
                                  if(!strcmp(cities[x], stopname[i])) {stops[i] = x;} // assigns stops a number depends what place name was enterd
                                }
                                  if(stops[i]>9 || stops[i]<0)
                                  {
                                   printf("\n Invalid place name please re enter: ");
                                   i--; 
                                   wrong=1;            
                                   }
                      }
    i get thisss

    http://s57.photobucket.com/albums/g2...ent=hmmmmm.jpg

    im trying to get the program to output a error messege when a invalid place name is put in and ask for re input of the name i just cant get it to go

  14. #119
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You badly need to work on that indentation.
    Code:
    const char *cities[] = {"London", "Glasgow", "Birmingham",	"Manchester", "Luton", "Poole", "Stafford", "Stoke", "Cardiff", "Derby"};
    
    	 else if(numstops>0)
    	 {
    
    		 for(i=0;i<numstops;i++) //loops round depeneding on how many stops was enterd
    		 {
    			 if(wrong !=1)
    			 {                     
    				 printf("\n Please enter the name for Stop %-1d: ",i+1);
    			 }
    			 wrong=0;  
    			 scanf("%16s",stopname[i]);
    			 size_t x;
    			 for(x = 0; x < sizeof(cities) / sizeof(*cities); x ++)
    			 {
    				 if(!strcmp(cities[x], stopname[i])) {stops[i] = x;} // assigns stops a number depends what place name was enterd
    			 }
    			 if(stops[i]>9 || stops[i]<0)
    			 {
    				 printf("\n Invalid place name please re enter: ");
    				 i--; 
    				 wrong=1;            
    			 }
    		 }
    You're missing a lot of braces (and code, too, I would bet).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #120
    Registered User
    Join Date
    Mar 2008
    Posts
    147
    Quote Originally Posted by Elysia View Post
    You badly need to work on that indentation.
    Code:
    const char *cities[] = {"London", "Glasgow", "Birmingham",	"Manchester", "Luton", "Poole", "Stafford", "Stoke", "Cardiff", "Derby"};
    
    	 else if(numstops>0)
    	 {
    
    		 for(i=0;i<numstops;i++) //loops round depeneding on how many stops was enterd
    		 {
    			 if(wrong !=1)
    			 {                     
    				 printf("\n Please enter the name for Stop %-1d: ",i+1);
    			 }
    			 wrong=0;  
    			 scanf("%16s",stopname[i]);
    			 size_t x;
    			 for(x = 0; x < sizeof(cities) / sizeof(*cities); x ++)
    			 {
    				 if(!strcmp(cities[x], stopname[i])) {stops[i] = x;} // assigns stops a number depends what place name was enterd
    			 }
    			 if(stops[i]>9 || stops[i]<0)
    			 {
    				 printf("\n Invalid place name please re enter: ");
    				 i--; 
    				 wrong=1;            
    			 }
    		 }
    You're missing a lot of braces (and code, too, I would bet).

    yeaaaaaaaaaaa i know my code is not the best at setting out but welll i leave things like that to the end
    i just dont know how to get to check the input place name and well if its not in the struct ask for re inputt

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading data from a text file
    By Dark_Phoenix in forum C++ Programming
    Replies: 8
    Last Post: 06-30-2008, 02:30 PM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. reading from text file
    By jamez in forum C Programming
    Replies: 3
    Last Post: 11-30-2005, 07:13 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM