简体   繁体   中英

parse ints from char array

I'm trying to read in a graph with space separated edges. Having an issue parsing from the char* buffer to the ints.

sample graph:

1   2 
1   3
2   3
3   4
4   5
1   5
5   6 
1   6 

output:

first edge: 1
second edge: 2
first edge: 0
second edge: 0
first edge: 1
second edge: 3
first edge: 0
second edge: 0
first edge: 2
second edge: 3
first edge: 0
second edge: 0
first edge: 3
second edge: 4
first edge: 0
second edge: 0
first edge: 4
second edge: 5
first edge: 0
second edge: 0
first edge: 1
second edge: 5
first edge: 0
second edge: 0
first edge: 5
second edge: 6
first edge: 0
second edge: 0
first edge: 0
second edge: 0
first edge: 1
second edge: 6
first edge: 0
second edge: 0
first edge: 0
second edge: 0

obviously all those zeroes shouldn't be there.

code:

#include <stdio.h>
#include <math.h>
#include <ctype.h>

int main(int argc, char* argv[]){   

    FILE *fin; 
    fin = fopen(argv[1], "r");
    int n_e = 0;
    char* buffer = (char*)malloc(2048);
    char* n1 = (char*)malloc(256); 
    char* n2 = (char*)malloc(256);
    int v_1 = 0; 
    int v_2 = 0;
    int flag = 0; 

    while(!feof(fin)){
        int bytes_read = fread(buffer, 1, 2048, fin);
        for(int i = 0; i < bytes_read; i++){
            if(isdigit(buffer[i])){
                if(flag == 0){ 
                    n1[v_1++] = buffer[i];
                }
                else 
                    n2[v_2++] = buffer[i]; 
            }
            else if(buffer[i] == ' ')
                flag = 1; 
            else{ //end of the line??
                n_e++;
                flag = 0; 
                n1[v_1++] = '\0';
                n2[v_2++] = '\0';
                int first = atoi(n1);
                int second = atoi(n2);
                printf("first edge: %d\n", first);
                printf("second edge: %d\n", second);
                v_1 = 0;
                v_2 = 0;
            }
        }
    }

return 0;
}

You can achieve the nub of what you want in a single line: the fscanf line. The rest is devoted to the framework and error checking - that's an essential part of any program. Given your graph edges as a text file:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *fin; 
    int first, second;
    if(argc < 2) {                                      // check # arguments
        return 0;                                       // or other action
    }
    fin = fopen(argv[1], "rt");
    if(fin == NULL) {                                   // check the file opened
        return 0;                                       // or other action
    }
    while(fscanf(fin, "%d%d", &first, &second) == 2) {  // check the number of items read
        printf("first edge: %d, second edge: %d\n", first, second);
    }
    fclose(fin);
    return 0;
}

Program output:

first edge: 1, second edge: 2
first edge: 1, second edge: 3
first edge: 2, second edge: 3
first edge: 3, second edge: 4
first edge: 4, second edge: 5
first edge: 1, second edge: 5
first edge: 5, second edge: 6
first edge: 1, second edge: 6

Note too, that feof is not used the way you did, as commented above.

You can check the value returned by sscanf() function in order to determine if the sample was parsed successfully from the line.

I rewrote you code to demonstrate a more efficient way to solve your problem:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MAX_LINE_LEN            (32)
#define MAX_EDGES_SAMPLES       (256)


/* Represents an Edge Object */
typedef struct edge_s
{
    int first;
    int second;
} edge_t;


int main( int argc, char * argv[] )
{
    FILE * pf = NULL;
    char line[ MAX_LINE_LEN + 1 ] = {0};
    int count = 0;
    int i = 0;

    edge_t edges[ MAX_EDGES_SAMPLES ]; /* Edges array */


    /* Initialize Edges array */
    memset( &edges, 0, sizeof( edges ) );

    /* Open input text file for reading */
    pf = fopen( argv[1], "r" );

    if(!pf)
    {
        printf("Error openning file: %s\n", argv[1] );
        return 1;
    }

    /* For each line... */
    while( fgets( line, MAX_LINE_LEN, pf ) )
    {
        edge_t aux;

        /* Parse Line */
        int ret = sscanf( line,  "%d %d", &aux.first, &aux.second );

        /* Ignore malformed lines */
        if( ret != 2 )
            continue;

        /* Add values to the Edges array */
        edges[count].first = aux.first;
        edges[count].second = aux.second;

        /* Increment Edges Count */
        count++;

        if( count >= MAX_EDGES_SAMPLES )
            break;
    }

    /* Free resource */
    fclose(pf);

    /* Display Edges array data */
    for( i = 0; i < count; i++ )
        printf("Edge[%d]: first=%d second=%d\n", i, edges[i].first, edges[i].second );

    return 0;
}

/* eof */

Hope it Helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM