我有一个文本文件,其中的数字用空格分隔,我希望将这些数字中的每一个存储在一个数组中,以便稍后在我的程序中使用。我的问题是识别数字更大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?
答案 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()
有很多选项和详细信息。