处理从行中读取值的最简单方法是使用strtod 向下工作。 strtod 将两个指针作为参数。第一个指向搜索数字(或前导+/-)的起点,以便将数字的字符串表示形式转换为数值(跳过所有前导空格)。第二个指针指向指针 (endptr) 将设置为转换中使用的最后一个字符之后的下一个字符。您从那里开始搜索下一个要转换的数字(例如,设置 p = ep; 并重复该过程)。
您可以查阅手册页以获取更多详细信息,但要验证转换是否成功,请检查指针是否不等于结束指针(意味着数字已转换)并检查以确保 errno 不是放。如果没有转换数字(意味着您有一个无效字符),您只需手动向前扫描该行,直到找到您的下一个 +/- 或 0-9(或者您点击 nul-terminating em> 字符)。
您希望通过保留一个简单的计数器并在数组已满时退出循环来保护您的数组边界并限制您尝试存储在向量数组中的值的数量。
这是一个简短的例子(NAN 和 INF 检查省略):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define VECSZ 5 /* if you need a constant, define one (or more) */
int main (int argc, char **argv) {
int i, n = 0;
double v[VECSZ] = {0.0};
char buf[BUFSIZ] = "";
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (n < VECSZ && fgets (buf, BUFSIZ, fp)) { /* read each line */
char *p = buf, *ep; /* pointer, end-pointer for strtod */
while (n < VECSZ) { /* convert vales in buf until VECSZ */
double tmp = strtod (p, &ep);
if (p != ep) { /* digits converted */
if (!errno) /* validate no error */
v[n++] = tmp; /* add to vector */
p = ep; /* update pointer */
}
else { /* no digits converted */
fprintf (stderr, "error: no digits converted.\n");
/* scan forward to next valid '+,-,0-9' */
while (*p && *p != '-' && *p != '+' && (*p < '1' || '9' < *p))
p++;
if (*p) /* numbers remain in line */
continue;
break; /* otherwise get next line */
}
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (i = 0; i < n; i++)
printf ("v[%d]=% g\n", i, v[i]);
return 0;
}
输入文件示例
$ cat dat/strtod_vect.txt
1 -2 3.1 0xf 0xcc
使用/输出示例
$ ./bin/strtod_vect dat/strtod_vect.txt
v[0]= 1
v[1]=-2
v[2]= 3.1
v[3]= 15
v[4]= 204
查看一下,如果您还有其他问题,请告诉我。您可以查看strtod(3) - Linux man page 了解更多详细信息和可以进行的错误检查。