带有数字到阵列的文本文件

时间:2015-12-06 15:16:23

标签: c arrays text-files

我有一个文本文件,其中的数字用空格分隔,我希望将这些数字中的每一个存储在一个数组中,以便稍后在我的程序中使用。我的问题是识别数字更大9。

例如:

10 9 13 20 29 29 12 9 3 59
12 14 42 45 65 21 12 
0 94 23 12 43 67 49 23 20  

如何检查数字是否属于大于9?

2 个答案:

答案 0 :(得分:1)

从文件读取数组中的任何值时,首先需要一个输入例程,将值读入所需的存储类型。你可以花一辈子的时间反复编写输入例程以匹配每个输入文件格式,或者你可以编写一个灵活的例程并再次使用它。 strtol(或任何其他strtoX函数)提供了一种简单的格式中立方式,无论格式如何,都可以从输入中解析值。 strtol的声明是:

long int strtol(const char *nptr, char **endptr, int base);

该函数接受一个指向作为第一个参数的字符串的指针。给定任何字符串,只需使用指针跳过所有非数字字符,并在遇到strtol-时将指针值传递给[0-9]strtol会将数字转换为数字,在遇到第一个非数字时停止,然后更新endptr以指向刚刚转换的数字后的第一个非数字。

使用endptr值并将字符串简化为下一个-[0-9]并使用该值作为该函数的下一个输入,您可以通过任何字符串并转换它包含的所有数字 - 无论输入格式如何。遇到'\n'时,只需重复下一行的过程,直到读取文件为止。

问题的下一部分只是比较转换为9的数字的值,并在数组中存储大于9的任何值,以便以后在程序中使用。与所有功能一样,您需要在整个过程中进行适当的错误检查,并相应地响应任何错误情况。

以下是一个简短的例子。 注意: strtol函数包含在一个简短的函数xstrtol中,它只是提供了所需的错误检查,而不会使代码的主体混乱。如果您有疑问,请告诉我们:

#include <stdio.h>
#include <stdlib.h> /* for strtol   */
#include <limits.h> /* for LONG_MIN/LONG_MAX */
#include <errno.h>  /* for errno    */

#define MAXL 256

long xstrtol (char *p, char **ep, int base);

int main (int argc, char **argv)
{
    int values[MAXL] = {0};
    char line[MAXL] = {0};
    size_t i, idx = 0;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) { /* validate file open */
        fprintf (stderr, "error: file open failen '%s'.\n", argv[1]);
        return 1;
    }

    /* read each line in file (up to MAXL chars per-line) */
    while (fgets (line, MAXL, fp)) {

        char *p = line;
        char *ep = p;
        int tmp;
        errno = 0;

        /* convert each string of digits into number */
        while (errno == 0) {

            /* skip any non-digit characters */
            while (*p && ((*p != '-' && (*p < '0' || *p > '9')) ||
                (*p == '-' && (*(p+1) < '0' || *(p+1) > '9')))) p++;
            if (!*p) break;

            /* convert string to number */
            tmp = (int)xstrtol (p, &ep, 10);

            /* test if tmp > 9 and store */
            if (tmp > 9)
                values[idx++] = tmp;

            if (errno) break;   /* check for error */

            if (idx == MAXL) {  /* check if array full */
                fprintf (stderr, "warning: MAXL values read.\n");
                break;
            }

            /* skip delimiters/move pointer to next digit */
            while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
            if (*ep)
                p = ep;
            else  /* break if end of string */
                break;
        }
    }
    if (fp != stdin) fclose (fp);

    printf ("\nvalues read from '%s'\n\n", argc > 1 ? argv[1] : "stdin");
    for (i = 0; i < idx; i++)
        printf ("  values[%3zu] : %d\n", i, values[i]);

    return 0;
}

/** a simple strtol implementation with error checking.
 *  any failed conversion will cause program exit. Adjust
 *  response to failed conversion as required.
 */
long xstrtol (char *p, char **ep, int base)
{
    errno = 0;

    long tmp = strtol (p, ep, base);

    /* Check for various possible errors */
    if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
        (errno != 0 && tmp == 0)) {
        perror ("strtol");
        exit (EXIT_FAILURE);
    }

    if (*ep == p) {
        fprintf (stderr, "No digits were found\n");
        exit (EXIT_FAILURE);
    }

    return tmp;
}

<强>编译

gcc -Wall -Wextra -O3 -o bin/fgets_xstrtol_select fgets_xstrtol_select.c

(将-O3优化替换为-g以生成调试符号)

输入文件

$ cat dat/intvalues.txt
10 9 13 20 29 29 12 9 3 59
12 14 42 45 65 21 12
0 94 23 12 43 67 49 23 20

使用/输出

$ ./bin/fgets_xstrtol_select <dat/intvalues.txt

values read from 'stdin'

  values[  0] : 10
  values[  1] : 13
  values[  2] : 20
  values[  3] : 29
  values[  4] : 29
  values[  5] : 12
  values[  6] : 59
  values[  7] : 12
  values[  8] : 14
  values[  9] : 42
  values[ 10] : 45
  values[ 11] : 65
  values[ 12] : 21
  values[ 13] : 12
  values[ 14] : 94
  values[ 15] : 23
  values[ 16] : 12
  values[ 17] : 43
  values[ 18] : 67
  values[ 19] : 49
  values[ 20] : 23
  values[ 21] : 20

答案 1 :(得分:0)

看哪,scanf()功能在其所有的荣耀中。 : - )

scanf()函数用于从文件流中读取格式化输入(包括stdin)。格式化我的意思是您希望输入采用可预测的格式,例如名称后跟空格后跟数字。格式字符串告诉scanf()要查找的内容,并且通常会忽略空格,除非它们确定事物的起点和终点。

在你的情况下会使用这样的东西:

int x = 0 ;

int numfound = 0 ;

numfound = scanf( "%d", &x ) ;

if( numfound == 0 )
{
    /* scanf() read nothing */
}
else
{
    /* scanf() did find a number and it's in 'x' */
}

scanf()有很多选项和详细信息。