使用strtol()从文件行中解析长值

时间:2013-07-16 09:19:19

标签: c parsing strtol

当我使用strtol函数从文件的这些行中解析长值时,

ffffffff8105b4a5 t send_signal

它只返回ffffffff而不是ffffffff8105b4a5 !!!

以下是代码:

 uint64_t value1;
 uint64_t value2;
 char *temp = (char *) malloc(100);
fgets(temp,512, fp);
strncpy(line1,temp,16);
value1 = strtol(line1,NULL,16);
printf("str_hex1 = %x\n",value1);
printf("str_hex2 = %x\n",value2);

3 个答案:

答案 0 :(得分:1)

您的配置似乎是sizeof(long) == 4(即32位long)。您可能希望查看strtoull() / strtoll()而不是strtoul() / strtol(),并使用[unsigned] long long变量代替......

编辑:实际上,不要介意[unsigned] long long位,因为您已经拥有uint64_t ...

答案 1 :(得分:1)

我根据Chrono的建议回答了我的评论:

缓冲区溢出漏洞

如果你分配100个字节作为I / O缓冲区,你应该告诉填充它的函数:

char *temp = malloc(100);
fgets(temp, 100, fp);

或者如果您在返回之前丢弃该缓冲区:

char temp[100];
fgets(temp, sizeof(temp), fp);

不必要的副本

为什么不简单

strtol(temp, NULL, 16);

使用fscanf(3)并格式化字符串以解析流

解析

之类的行
ffffffff8105b4a5 t send_signal

我会写类似于

的东西
#include <inttypes.h>

int rv;
uint64_t col1;
char col2;
char col3[64];

rv = fscanf(fp, SCNx64 " %c %64s", &col1, &col2, col3);
if (rv != 3) {
    /* error treatment */
}

这比一系列fgetsstrtoulstrcpy简洁得多。它还节省了一些内存复制操作,因为它直接在FILE*缓冲区上运行。

此外,对于与col3一样的情况,GNU(以及即将发布的POSIX.1)*scanf具有转换格式扩展名"%ms",它为字符串分配必要的缓冲区,因此您不需要必须(并且不要遇到缓冲区溢出)。请记住,尽管如此调用free()

答案 2 :(得分:-1)

似乎strtol超出范围(0xffffffff或更高是根据limits.h的ULONG_MAX和strtol的{​​{3}})。 虽然传递的值(8105b4a5)小于0xffffffff,但它大于LONG_MAX(取决于系统),这是strtol可以处理的最大数字。

由于您使用的是无符号长整数,因此函数strtoul(请参阅definition)可能更合适。

要确保是因为此范围问题,请检查您的本地限制。

希望有效。

*斯特