Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
205 views
in Technique[技术] by (71.8m points)

read rows of ints from a file in C

how can I read rows of ints from a txt file in C. input.txt

3

5 2 3

1

2 1 3 4

the first 3 means there are 3 lines in all. I write a c++ version using cin cout sstream but I wonder how can I make it in C using fscanf or other c functions. I need to handle each line of integers separately.

I know I can use getline to read the whole line into a buffer, then parse the string buffer to get the integers. Can I just use fscanf?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What you ultimately want to do is free yourself from having to worry about the format of your inputfile. You want a routine that is flexible enough to read each row and parse the integers in each row and allocate memory accordingly. That greatly improves the flexibility of your routine and minimizes the amount of recoding required.

As you can tell from the comments there are many, many, many valid ways to approach this problem. The following is a quick hack at reading all integers in a file into an array, printing the array, and then cleaning up and freeing the memory allocated during the program. (note: the checks for reallocating are shown in comments, but omitted for brevity).

Note too that the storage for the array is allocated with calloc which allocates and sets the memory to 0. This frees you from the requirement of keeping a persistent row and column count. You can simply iterate over values in the array and stop when you encounter an uninitialized value. Take a look over the code and let me know if you have any questions:

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

#define MROWS 100
#define MCOLS 20

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

    if (argc < 2) {
        fprintf (stderr, "error: insufficient input.  usage: %s filename
", argv[0]);
        return 1;
    }

    FILE *fp = fopen (argv[1], "r");
    if (!fp) {
        fprintf (stderr, "error: file open failed for '%s'.
", argv[1]);
        return 1;
    }

    char *line = NULL;          /* NULL forces getline to allocate  */
    size_t n = 0;               /* max chars to read (0 - no limit) */
    ssize_t nchr = 0;           /* number of chars actually read    */
    int **array = NULL;         /* array of ptrs to array of int    */
    size_t ridx = 0;            /* row index value                  */
    size_t cidx = 0;            /* col index value                  */
    char *endptr = NULL;        /* endptr to use with strtol        */

    /* allocate MROWS (100) pointers to array of int */
    if (!(array = calloc (MROWS, sizeof *array))) {
        fprintf (stderr, "error: array allocation failed
");
        return 1;
    }

    /* read each line in file */
    while ((nchr = getline (&line, &n, fp)) != -1) 
    {
        /* strip newline or carriage return (not req'd) */
        while (line[nchr-1] == '
' || line[nchr-1] == '
')
            line[--nchr] = 0;

        if (!nchr)      /* if line is blank, skip */
            continue;

        /* allocate MCOLS (20) ints for array[ridx] */
        if (!(array[ridx] = calloc (MCOLS, sizeof **array))) {
            fprintf (stderr, "error: array[%zd] allocation failed
", ridx);
            return 1;
        }

        cidx = 0;       /* reset cidx               */
        char *p = line; /* assign pointer to line   */

        /* parse each int in line into array    */
        while ((array[ridx][cidx] = (int)strtol (p, &endptr, 10)) && p != endptr)
        {
            /* checks for underflow/overflow omitted */

            p = endptr; /* increment p      */
            cidx++;     /* increment cidx   */
            /* test cidx = MCOLS & realloc here */
        }
        ridx++;         /* increment ridx   */

        /* test for ridx = MROWS & realloc here */
    }

    /* free memory and close input file */
    if (line) free (line);
    if (fp) fclose (fp);

    printf ("
Array:

  number of rows with data: %zd

", ridx);

    /* reset ridx, output array values */
    ridx = 0;
    while (array[ridx])
    {
        cidx = 0;
        while (array[ridx][cidx])
        {
            printf ("  array[%zd][%zd] = %d
", ridx, cidx, array[ridx][cidx]);
            cidx++;
        }
        ridx++;
        printf ("
");
    }

    /* free allocated memory */
    ridx = 0;
    while (array[ridx])
    {
        free (array[ridx]);
        ridx++;
    }
    if (array) free (array);

    return 0;
}

input file

$ cat dat/intfile.txt
3

5 2 3

1

2 1 3 4

program output

$ ./bin/readintfile dat/intfile.txt

Array:

  number of rows with data: 4

  array[0][0] = 3

  array[1][0] = 5
  array[1][1] = 2
  array[1][2] = 3

  array[2][0] = 1

  array[3][0] = 2
  array[3][1] = 1
  array[3][2] = 3
  array[3][3] = 4

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...