【问题标题】:strtol not converting string from read(fd,buffer,ssize_t)strtol 不从 read(fd,buffer,ssize_t) 转换字符串
【发布时间】:2013-01-10 17:02:04
【问题描述】:

strtol 不会转换我从读取文本文件中获得的字符串。

int getNumFiles(int archive){
off_t cur=lseek(archive,20,SEEK_SET);
if(cur==-1){
    printf("lseek ERROR\n");
    exit(-1);
}
bool b=true;
char headerSizeBuffer[4];
char *end;

while(b){
    int numRead=read(archive,headerSizeBuffer,3);
    if(numRead != 3){
        printf("read ERROR\n");
        exit(-1);
    }
    headerSizeBuffer[3]='\0';
    printf("headerSizeBuffer=%s  with length=%ld\n",headerSizeBuffer,strlen(headerSizeBuffer));
    long headerSize=strtol(headerSizeBuffer,&end,10);//atol(headerSizeBuffer);
    printf("headerSize=%ld\n",headerSize);

    if (!*end)
        printf("Converted successfully\n");
    else
        printf("Conversion error, non-convertible part: %s\n", end);
    b=false;
}

return 1;

}

当我运行编译后的代码时,控制台会给我这个

headerSizeBuffer=031l_archive  with length=12
headerSize=31
Conversion error, non-convertible part: l_archive

我要做的就是将 031 转换为值为 31 的 long 或 int。

【问题讨论】:

  • 您没有显示每个变量的声明,因此很难确定。 read() 不保证字符串的空终止。 OTOH,strlen() as 3 的报告表明你应该没问题,你不应该在*end 中得到奇数。您的代码是否在没有警告的情况下编译?是否包含所有标题(<unistd.h><string.h><stdlib.h><stdio.h>)?
  • 声明出现在我向您展示的代码之前,它们就像这样 char* headerSizeBuffer;字符 * 结束;是的,我拥有所有这些头文件,并且在编译时没有收到警告
  • 问题是你没有为 headerSizeBuffer 分配空间!您正在使用未初始化的指针。
  • @JonathanLeffler 不要去点击来自 SO 的那些“点击更新”消息。 :-)

标签: c strtol


【解决方案1】:

很可能是您没有为 headerSizeBuffer 分配空间或足够的空间,并且在 printf 调用(开始)和 strtol 调用(结束)之间的某个时间被覆盖。

编辑:来自上面的评论:“char* headerSizeBuffer”

是的,我是对的。由于您尚未分配任何空间,因此您的行为未定义……这意味着可能会发生任何行为,包括您所看到的。确保为 headerSizeBuffer 分配足够的空间,方法是将其设置为指向足够的内存(可能来自 malloc,也可能是数组,或各种其他不太常见的方式),或者更适合您的情况,因为大小需要在编译时知道,将其声明为数组而不是指针:

char headerSizeBuffer[4];

确保在将字符串传递给 strtol 之前设置 headerSizeBuffer[3] = '\0` 以终止字符串。

【讨论】:

  • 我该怎么做? malloc?
  • 没关系 char headerSizeBuffer[4];作品。非常感谢大家
  • @user2014761 如果在编译时不知道缓冲区的大小,您可以使用 malloc,但既然是您的情况,请使用数组。
  • @user2014761 乐于提供帮助。当你得到满意的答案时,你应该接受它。 (您可能需要等待几分钟。)
  • 现在我遇到了新问题。当我将声明更改为 char headerSizeBuffer[4];从我的文件一开始,我的阅读电话现在就变得更加垃圾了。输出变为 headerSizeBuffer=031l_archive 长度=12 headerSize=31 转换错误,不可转换部分:l_archive 我的文件开头有“peter_rindal_archive031ls.py 259 1358313654 0000001865 ...”不知何故,读取变得一团糟。
【解决方案2】:

这是因为 strtol 需要一个以空字符结尾的字符串,而您的 read() 只需要 3 个字符。 strtol 然后看不到字符串的结尾并继续读取垃圾。你需要设置headerSizeBuffer[3] = 0

【讨论】:

  • 这也是我的第一反应,但是...strtol() 之前的printf() 决定了strlen(headerSizeBuffer) == 3headerSizeBuffer[3] 处有一个 null 可能是巧合,但输出中的信息表明它在那里,这使得从 strtol() 的返回令人费解。
  • 我在调用 strtol 之前添加了 headerSizeBuffer[3] = 0 但得到了相同的结果
  • 查看我的回答...您没有为缓冲区分配任何空间。
  • @user2014761 你还需要将 headerSizeBuffer 声明为char headerSizeBuffer[4],而不是char* headerSizeBuffer。 (char * 是一个未初始化的指针,所以你会得到未定义的行为。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多