Search code examples
cinputfilereaderscanffile-read

Reading C Input with skipping commas and columns


I am new to C and i wanted to do File Read operations. Here i have input.txt which contains :

(g1,0.95) (g2,0.30) (m3,0.25) (t4,0.12) (s5,0.24)
(m0,0.85) (m1,0.40) (m2,0.25) (m3,0.85) (m4,0.5) (m5,0.10)

now, i wanted to save k1,k2,k3 etc in array keys[10] and the 0.15,0.10,0.05 in the array values[10]

is there any way to skip the first "(", ignore "," and " " without specifying one by one? i tried to search for tutorials and i heard that i can read several characters before and after with it, but i think i misled them. Can somebody show me how to achieve this?

#include <stdio.h>
#define HEIGHT 2
#define WIDTH  6

int main(void)
{
     FILE *myfile;
     char nothing[100];
     char leaf[2];
     float value;

     char keys[10];
     float values[10];

     int i;
     int j;
     int counter=0;

     myfile=fopen("input.txt", "r");

     for(i = 0; i < HEIGHT; i++)
     { 
         for (j = 0 ; j < WIDTH; j++)
         { 
             fscanf(myfile,"%1[^(],%s[^,],%4f[^)]",nothing,leaf,value);
             printf("(%s,%f)\n",leaf,value);
             keys[counter]=leaf;
             values[counter]=value;
             counter++;
         }
         printf("\n");
     }

     fclose(myfile);

 }

Solution

  • Here's how I would do it:

    int main( void )
    {
        // open the file
        FILE *fp;
        if ( (fp = fopen("test.txt", "r")) == NULL )
            exit( 1 );
    
        // declare the arrays
        char keys[10][32];
        float values[10];
    
        // load them up
        int i;
        for ( i = 0; i < 10; i++ )
            if ( fscanf( fp, " ( %31[^ ,] ,%f )", keys[i], &values[i] ) != 2 )
                break;
        int count = i;
    
        // print them out
        printf( "%d\n", count );
        for ( i = 0; i < count; i++ )
            printf( "%s %.2f\n", keys[i], values[i] );
    
        // close the file
        fclose( fp );
    }
    

    The key is the format specifier for the scanf which consists of 5 elements. Note that I'm using underscores to show where the spaces are

    _(_      skips whitespace, matches the opening parenthesis, skips whitespace
    %31[^_,] reads at most 31 characters, stopping on a space or a comma
    _,       skips whitespace, matches the comma
    %f       reads a floating point value
    _)       skips whitespace, matches the closing parenthesis