【问题标题】:Why is atoi returning random numbers?为什么atoi返回随机数?
【发布时间】:2010-01-28 14:36:53
【问题描述】:

我正在尝试从文本文件(时间)中读取数据。并将其转换为可以 DiffTime'ed 到当前系统时间的东西。

我现在非常接近让它正常工作,我可以品尝它,但我遇到了一个我无法解决的问题。 (我对 C 语言有非常基本的掌握)。

此程序从文本文件中读取数据,将其拆分为两个字符数组,然后尝试使用atoi 将其转换为整数。但是,我在第二个atoi 通话中遇到了问题。

从底部的两个printf 语句中,我应该得到:

12 34

但由于某种原因,我在这些方面得到了一些东西。

12 3412

我认为atoi 超出了其中一个 char 数组的边界,或者我的 char 数组太长或太短。无论哪种方式,我都无法理解发生了什么。

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define COPYMODE 0644

int main (int argc, char *argv[]){
    int  i, nRead, fd;

    int  source;
    int  ihour;
    int  imin;

    int  STATE_OK = 0;
    int  STATE_WARNING  = 1;
    int  STATE_CRITICAL = 2;
    int  STATE_UNKNOWN  = 3;
    /* indicates if system is paused 1 = System is paused, 0 = System running */
    int  system_paused  = 0; 

    char filebuf[5]; 
    char hourbuf[2];
    char minbufer[2];

    if((fd = open(argv[1], O_RDONLY)) == -1)
    {
        printf("failed open : %s", argv[1]);
    }
    else
    {
        nRead = read(fd, filebuf, 5);
    }
    close(source);

    printf("filebuffer %s\n", filebuf);

    hourbuf[0] = filebuf[0];
    hourbuf[1] = filebuf[1];

    printf("Hour Buffer %c%c\n", hourbuf[0],hourbuf[1]);

    minbufer[0] = filebuf[2];
    minbufer[1] = filebuf[3];

    printf("Min Buffer %c%c\n", minbufer[0],minbufer[1]);

    imin = atoi(minbufer);
    ihour = atoi(hourbuf);


    printf("hour as int %d\n", ihour);
    printf("min as int %d\n", imin);

    return 0;
}

【问题讨论】:

    标签: c integer atoi


    【解决方案1】:

    您需要空终止字符串。在调用 atoi 之前,将 hourbuf 和 minbufer 1 加长并在末尾添加一个 0。这两个缓冲区在堆栈上是相邻的,因此读取 minbufer 也会扫描到 hourbuf。

    【讨论】:

    • +1,因为您还对奇怪的“3412”输出给出了很好的解释。
    • 我的大脑告诉我这个,但我不知道如何阻止它,这让我发疯了。我来自没有“空终止”的编程背景,所以我一直忘记它.... :) 感谢您的回复。
    【解决方案2】:

    您忘记用零终止您的 char 缓冲区。

    char hourbuf[2];
    char minbufer[2];
    

    应该是

    char hourbuf[3];
    char minbufer[3];
    
    hourbuf[2] = '\0';
    minbufer[2] = '\0';
    

    【讨论】:

      【解决方案3】:

      atoi 假定它的参数是一个 C 风格的字符串,这意味着它必须包含一个尾随 nul 字符。

      您手工制作的伪字符串无法确保这一点。

      一种解决方案是放大它们并将最后一个元素设置为'\0

      char hourbuf[3];
      int hour;
      ...
      hourbuf[0] = filebuf[0];
      hourbuf[1] = filebuf[1];
      hourbuf[2] = '\0';
      hour = atoi(hourbuf);
      

      【讨论】:

        【解决方案4】:

        你忘了空终止:

        minbufer[2] = '\0'
        

        【讨论】:

        • 你的想法是对的,所以我不反对。但是,我怀疑您投了反对票,因为您没有指出 minbufer 需要 3 个字符 ..
        • 我考虑过,但我认为编码器真的应该能够自己解决这个问题。
        • 你也是正确的,亚历克斯 :) 我本来可以解决这个问题的,虽然没有你们那么快,但它会打击我。这种语言对我来说是一个真正的学习曲线:) 为回复欢呼。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-26
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 2018-09-23
        • 1970-01-01
        • 2017-01-17
        相关资源
        最近更新 更多