我有一个文本文件,其中一行的数字用空格分隔,如下例所示:
1 -2 3.1 0xf 0xcc
使用C程序解析文件后,结果应保存在向量中,其内部结构应为:
V[0]=1
V[1]=-2
V[2]=3.1
V[3]=15
V[4]=204
基本上我需要将以0x开头的数字转换为十进制数。
我已尝试将所有元素存储在char矢量中,然后将其转换为数字,但没有太多成功。
对C中的一段代码的任何帮助将不胜感激。谢谢
答案 0 :(得分:1)
整数类型需要strtol函数。您可以使用endptr
遍历字符串。对于double
,您可以使用atof函数,但必须首先检查字符串是否包含点。
编辑:提及user3386109 strtod是double
的更好解决方案。
假设你有一个数组中的字符串:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char numbers_str[] = "1 -2 3.1 0xf 0xcc";
int ints[10];
double doubles[10];
int ints_idx = 0, doubles_idx = 0;
const char delims[] = " ";
char *it = strtok(numbers_str, delims);
while(it != NULL)
{
char *dot_it = strchr(it, '.');
// When a dot is found then a double number is found
if(dot_it)
doubles[doubles_idx++] = strtod(it, NULL);
// When a dot is not found then we've got an integer
else
ints[ints_idx++] = strtol(it, NULL, 0);
it = strtok(NULL, delims);
}
printf("Integers found: \n");
for(int i = 0; i < ints_idx; ++i)
printf("%d\n", ints[i]);
printf("Double numbers found: \n");
for(int i = 0; i < doubles_idx; ++i)
printf("%f\n", doubles[i]);
}
答案 1 :(得分:1)
您可以拥有look at sscanf
。这是一个简单的计划。我相信你可以从这里接受:
#include <stdio.h>
int main(void)
{
char *hex = "0xF";
int i= 0;
sscanf(hex, "%x", &i);
printf("%d", i);
}
答案 2 :(得分:0)
处理从该行读取值的最简单方法是使用strtod
开始工作。 strtod
将两个指针作为参数。第一个指向开始点以搜索数字(或前导+/-
),以便将数字的字符串表示转换为数字值(跳过所有前导空格)。第二个指向指针(endptr
)将被设置为转换中使用的最后一个字符之后的下一个字符。您开始搜索要从中转换的下一个数字(例如设置p = ep;
并重复此过程)。
您可以查阅手册页以获取更多详细信息,但要验证转换是否成功,请检查指针是否与结束指针不同(表示数字已转换),并检查以确保errno
没设定。如果没有转换的数字(意味着您的字符无效),您只需要手动向前扫描直到找到下一个+/-
或0-9
(或者您点击 nul) - 终止字符)。
您希望保护数组边界,并通过保留一个简单的计数器并在阵列已满时退出循环来限制您尝试存储在向量数组中的值的数量。
这是一个简短的例子(省略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以获取更多详细信息和可以执行的错误检查。