how to tokenize string to array of int in c?

前端 未结 6 1599
暖寄归人
暖寄归人 2020-12-15 01:01

Anyone got anything about reading a sequential number from text file per line and parsing it to an array in C?

What I have in a file:

12 3 45 6 7 8
3         


        
6条回答
  •  独厮守ぢ
    2020-12-15 01:56

    The following code may be what you're looking for. Hopefully you won't need too much of a description given the comments but, if you have questions, feel free to ask.

    It basically uses an fgets loop to read each line in and strtok to separate that line into fields. It constructs a linked list of integer arrays which contain the actual data - you can see the use of that linked list in the code at the end that dumps out the table.

    It also has a means by which it can handle arbitrary-sized lines in the input file without buffer overflow (subject to memory constraints of course). Keep in mind that the strtok only expects one space between each field on the line although that could be recoded to handle multiple spaces or even any amount of white space. I've kept that bit simple since the code was already getting a little big :-)

    The atoi function is used to convert the individual word on each line into integers. If you want error checking on those, I'd call your own variant which also checks that all characters in the word are numeric.

    Using your input file of:

    12 3 45 6 7 8
    3 5 6 7
    7 0 -1 4 5
    

    it produces output along the lines of:

    0x97b5170, size = 6:
       12 3 45 6 7 8
    0x97b51d0, size = 4:
       3 5 6 7
    0x97b51e0, size = 5:
       7 0 -1 4 5
    

    Here's the code that produced that output:

    #include 
    #include 
    #include 
    #include 
    
    // This is the linked list of integer arrays.
    
    typedef struct _tIntArray {
        int size;
        int *array;
        struct _tIntArray *next;
    } tIntArray;
    static tIntArray *first = NULL;
    static tIntArray *last = NULL;
    
    // Add a line of integers as a node.
    
    static int addNode (char *str) {
        tIntArray *curr;  // pointers for new integer array.
        char *word;       // word within string.
        char *tmpStr;     // temp copy of buffer.
        int fldCnt;       // field count for line.
        int i;
    
        // Count number of fields.
    
        if ((tmpStr = strdup (str)) == NULL) {
            printf ("Cannot allocate duplicate string (%d).\n", errno);
            return 1;
        }
        fldCnt = 0;
        for (word = strtok (tmpStr, " "); word; word = strtok (NULL, " "))
            fldCnt++;
        free (tmpStr);
    

     

        // Create new linked list node.
    
        if ((curr = malloc (sizeof (tIntArray))) == NULL) {
            printf ("Cannot allocate integer array node (%d).\n", errno);
            return 1;
        }
    
        curr->size = fldCnt;
        if ((curr->array = malloc (fldCnt * sizeof (int))) == NULL) {
            printf ("Cannot allocate integer array (%d).\n", errno);
            free (curr);
            return 1;
        }
        curr->next = NULL;
    
        for (i = 0, word = strtok (str, " "); word; word = strtok (NULL, " "))
            curr->array[i++] = atoi (word);
    
        if (last == NULL)
            first = last = curr;
        else {
            last->next = curr;
            last = curr;
        }
    
        return 0;
    }
    

     

    int main(void) {
        int lineSz;       // current line size.
        char *buff;       // buffer to hold line.
        FILE *fin;        // input file handle.
        long offset;      // offset for re-allocating line buffer.
        tIntArray *curr;  // pointers for new integer array.
        int i;
    
        // Open file.
    
        if ((fin = fopen ("qq.in", "r")) == NULL) {
            printf ("Cannot open qq.in, errno = %d\n", errno);
            return 1;
        }
    
        // Allocate initial line.
    
        lineSz = 2;
        if ((buff = malloc (lineSz+1)) == NULL) {
            printf ("Cannot allocate initial memory, errno = %d.\n", errno);
            return 1;
        }
    
        // Loop forever.
    
        while (1) {
            // Save offset in case we need to re-read.
    
            offset = ftell (fin);
    

     

            // Get line, exit if end of file.
    
            if (fgets (buff, lineSz, fin) == NULL)
                break;
    
            // If no newline, assume buffer wasn't big enough.
    
            if (buff[strlen(buff)-1] != '\n') {
                // Get bigger buffer and seek back to line start and retry.
    
                free (buff);
                lineSz += 3;
                if ((buff = malloc (lineSz+1)) == NULL) {
                    printf ("Cannot allocate extra memory, errno = %d.\n", errno);
                    return 1;
                }
                if (fseek (fin, offset, SEEK_SET) != 0) {
                    printf ("Cannot seek, errno = %d.\n", errno);
                    return 1;
                }
                continue;
            }
    
            // Remove newline and process.
    
            buff[strlen(buff)-1] = '\0';
            if (addNode (buff) != 0)
                return 1;
        }
    

     

        // Dump table for debugging.
    
        for (curr = first; curr != NULL; curr = curr->next) {
            printf ("%p, size = %d:\n  ", curr, curr->size);
            for (i = 0; i < curr->size; i++)
                printf (" %d", curr->array[i]);
            printf ("\n");
        }
    
        // Free resources and exit.
    
        free (buff);
        fclose (fin);
        return 0;
    }
    

提交回复
热议问题