【问题标题】:C Convert String to Ints IssueC将字符串转换为整数问题
【发布时间】:2009-07-30 11:15:29
【问题描述】:

我正在尝试解析嵌入式系统上的一些输入。 我期待这样的事情:

SET VARNAME=1,2,3,4,5,6,7,8,9,10\0

当我将单独的字符串转换为整数时,如果字符串以 8 开头,atoi()strtol() 似乎都返回 0。

这是我的代码:

char *pch, *name, *vars;
signed long value[256];
int i;

#ifdef UARTDEBUG
    char convert[100];
#endif
if(strncmp(inBuffer, "SET",3)==0)
{
    pch = strtok(inBuffer," ");
    pch = strtok(NULL," ");
    name = strtok(pch, "=");
    vars = strtok(NULL,"=");

    pch = strtok(vars,",");

    i = 0;
    while(pch != NULL)
    {
        value[i] = atoi(pch);
        #ifdef UARTDEBUG
            snprintf(convert, sizeof(convert), "Long:%d=String:\0", value[i]);
            strncat(convert, pch, 10);
            SendLine(convert);
        #endif
        i++;
        pch = strtok(NULL,",");

        // Check for overflow
        if(i > sizeof(value)-1)
        {
            return;
        }
    }    

    SetVariable(name, value, i);
}

通过它:

SET VAR=1,2,3,4,5,6,7,8,9,10\0

在我的 uart 调试中提供以下内容:

Long:1=String:1                                                                
Long:2=String:2                                                                
Long:3=String:3                                                                
Long:4=String:4                                                                
Long:5=String:5                                                                
Long:6=String:6                                                                
Long:7=String:7                                                                
Long:0=String:8                                                                
Long:9=String:9                                                                
Long:10=String:10

更新:

我在 'value[i] = atoi(pch);' 之前和之后都检查了 inBuffer并且它是相同的,并且似乎已被分割到正确的位置。

S  E  T     V  A  R     1     2     3     4     5     6     7     8     9  ,  1  0
53 45 54 00 56 41 52 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39 2c 31 30 00 00 00 00 

更新 2:

我的 UARTDEBUG 部分目前为:

        #ifdef UARTDEBUG
            snprintf(convert, 20, "Long:%ld=String:%s", value[i], pch);
            SendLine(convert);
        #endif

如果我注释掉 snprintf() 行,一切都会完美运行。那么这是怎么回事呢?

【问题讨论】:

  • value[] 的声明是什么?
  • 如果你向我们展示整个函数(或者至少是所有接触到的变量的声明),可能会发现错误
  • 可能不会导致您遇到的问题,但 atol() 可能是您更好的选择,因为您将其声明为有符号长值 [256]
  • 格式有什么问题?只需执行snprintf(convert, sizeof(convert), "Long:%ld=String:%s", value[i], pch);。特别注意%ld

标签: c string atoi


【解决方案1】:

你不能试着写你自己的atoi吗? 它有十行长,然后您可以轻松调试它(并检查问题到底出在哪里)

  • '0' = 0x30
  • '1' = 0x31

等等,你只需要做类似的事情

string[x] - 0x30 * pow(10, n)

对于您拥有的每个数字

【讨论】:

    【解决方案2】:

    不相关,但是

    if(i > sizeof(value)-1)
                    {
                            return;
                    }
    

    应该是

    if(i == sizeof(value)/sizeof(value[0]) )
                    {
                            return;
                    }
    

    如果其他代码以错误的方式进行溢出检查并因此它们覆盖了您的部分字符串,则可能是问题的原因

    【讨论】:

    • 字符串似乎完好无损,我的猜测是 atoi 局部变量正在损坏
    【解决方案3】:

    我刚刚尝试在我自己的系统上编译和运行您的示例代码。输出是正确的(即 '8' 出现在它应该在输出字符串中的位置),这向我表明在您提供给我们的代码范围之外还有其他事情发生。

    我要冒昧地说你的一个变量或函数正在践踏你的输入字符串或其他一些变量或数组。 SendLine 和 SetVariable 是值得一看的地方。

    但更重要的是,您没有向我们提供帮助您解决问题的工具。当要求人们帮助您调试程序时,提供一个简单的测试用例,包含完整的源代码,以说明问题。否则,我们只能猜测问题出在哪里,这让我们感到沮丧,对您来说也无济于事。

    【讨论】:

    • 我已经解决了这个问题,似乎一些 snprintf 局部变量溢出到 atoi 局部变量中。由于某种原因,snprintf 在这个嵌入式系统上引起了整个世界的问题。发布测试用例的主要问题是,除非您使用相同的编译器、库和嵌入式处理器进行测试,否则我们可能不会调试相同的东西。我发布了一个示例字符串,我想知道是否有什么明显的错误。
    【解决方案4】:

    atoi 为无法呈现为数字的内容返回 0 - 这只是一种预感,但您是否尝试过转储字符串的二进制表示(或者甚至检查字符串长度是否匹配)?

    【讨论】:

    • 这是我午饭后的下一步!
    猜你喜欢
    • 2011-05-05
    • 1970-01-01
    • 2011-07-31
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多