从C中的文件中读取int行

时间:2015-03-05 06:24:27

标签: c

如何从C中的txt文件中读取int行。 input.txt中

3

5 2 3

1

2 1 3 4

前3个意味着共有3行。 我用cin cout sstream写了一个c ++版本 但我想知道如何使用fscanf或其他c函数在C中制作它。 我需要分别处理每一行整数。

我知道我可以使用getline将整行读入缓冲区,然后解析字符串缓冲区以获取整数。 我可以使用fscanf吗?

2 个答案:

答案 0 :(得分:3)

您最终想要做的是让您不必担心输入文件的格式。您需要一个足够灵活的例程来读取每一行并解析每一行中的整数并相应地分配内存。这极大地提高了日常工作的灵活性,并最大限度地减少了所需的重新编码量。

正如您从评论中可以看出的那样,有许多很多有效方法可以解决这个问题。以下是将文件中的所有整数读入array,打印数组,然后清理并释放程序中分配的内存的快速入侵。 (注意:重新分配的检查显示在注释中,但为简洁起见省略)。

另请注意,数组的存储分配有calloc,它将内存分配并设置为0。这使您免于保持持久行和列数的要求。您可以简单地迭代数组中的值,并在遇到未初始化的值时停止。如果您有任何问题,请查看代码并告诉我:

#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\n", argv[0]);
        return 1;
    }

    FILE *fp = fopen (argv[1], "r");
    if (!fp) {
        fprintf (stderr, "error: file open failed for '%s'.\n", 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\n");
        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] == '\r' || line[nchr-1] == '\n')
            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\n", 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 ("\nArray:\n\n  number of rows with data: %zd\n\n", ridx);

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

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

    return 0;
}

输入文件

$ cat dat/intfile.txt
3

5 2 3

1

2 1 3 4

节目输出

$ ./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

答案 1 :(得分:1)

在C(非C ++)中,您应该将fgetssscanf函数合并。

修改

但作为问题的答案“我可以使用fscanf吗?”

尝试此示例(fgetc的使用允许使用fscanf代替fgets + sscanf):

    int lnNum = 0;
    int lnCnt = 0; // line counter
    int ch; // single character
    // read number of lines
    fscanf(f, "%d", &lnNum);
    if(lnNum < 1)
    {
        return 1;  // wrong line number
    }
    // reading numbers line by line
    do{
        res = fscanf(f, "%d", &num);
        // analyse res and process num
        // .... 

        // check the next character
        ch = fgetc(f);
        if(ch == '\n')
        {
            lnCnt++; // one more line is finished
        }
    } while (lnNum > lnCnt && !feof(f) );

注意:当您的文件只有单个'\ n'或空格分隔的数字时,此代码可用,对于字母或组合的情况,number \n(换行前的空格)它变得不稳定