使用itoa()会导致:“赋值从整数中生成指针而不使用强制转换”

时间:2011-02-08 00:47:15

标签: c string type-conversion integer prototype

我正在研究C语言中的BCD(二进制编码十进制)并负责编写不同的bcd函数。

我需要将整数i编码为大小为n的缓冲区char *。成功时函数返回0或溢出时返回-1(编码i需要大于n的缓冲区)。

以下是功能:int bcd_encode(int i, int n, char *s)

和示例输入:assert(bcd_encode(a, 128, s) == 0);

我正在编写函数bcd_encode的代码,如果我错了,请更正我,但我相信函数,只有在函数中,如果你有一些func(char x[])和char func(char *x)他们会是一回事吗?所以你可以将它们看作char数组。如果它在函数定义之外char x[];将是一个char数组,而char *x;将是一个指针。

int bcd_encode(int i, int n, char *s){  
    int j = 0;  
    s = itoa(i, s, n+1);  
}

但是这会返回一个警告“赋值从没有强制转换的整数生成指针”和itoa的未定义符号。我尝试了一些不同的变体

* s = itoa(i); s = itoa(i); s = itoa(i,s,n + 1);

任何帮助将不胜感激。提前谢谢!

4 个答案:

答案 0 :(得分:1)

#include <stdlib.h>

如果不包含此内容,编译器对itoa()一无所知,并假设它返回int

答案 1 :(得分:1)

你说:

  

...如果我错了,请纠正我,但我相信一个函数,只有在函数中,如果你有一些函数(char x [])和char func(char * x)它们将是相同的事情?所以你可以将它们看作char数组。如果它在函数定义之外char x [];将是一个char数组和char * x;将是一个指针。

最好将它们视为函数内部的指针(而不是两者作为数组),但是你已经得到了关键点 - 在函数参数列表中,数组和指针之间的区别是模糊的,但是其他指针和数组是不同的。

在代码中,由于假定itoa()在没有相反信息的情况下返回一个整数,所以你不能将它存储在指针或指针中(不使用大锤演员,这会留下你的代码坏了。)

itoa()返回什么?它不是标准的C函数(不在ISO / IEC 9899:1999中,也不在POSIX中)。 Wikipedia表示它不返回任何值,因此您不应将其值分配到任何位置。 Linux将其作为<stdlib.h>中的非标准扩展,使用不同的接口返回char *(这是其第二个参数的值)。您可以放心地忽略返回值;实际上,您也可以执行赋值(在包含标题之后),但赋值是无操作。您确实需要知道该函数是非标准的,它具有各种定义,因此您必须了解适合您的平台的内容,或者避免使用它(可能使用snprintf()代替)。


引用链接的Linux手册页:

char* itoa (int __val, char * __s, int __radix)
     

将整数转换为字符串。

     

函数itoa()将val中的整数值转换为将存储在s下的ASCII表示形式。调用者负责在s中提供足够的存储空间。

     

注意:
   缓冲区的最小大小取决于基数的选择。例如,如果基数为2(二进制),则需要提供最小长度为8 * sizeof(int)+ 1个字符的缓冲区,即每个位一个字符加一个字符串终止符。使用较大的基数将需要较小的最小缓冲区大小。   的警告:
   如果缓冲区太小,则存在缓冲区溢出的风险。   使用基数作为基数进行转换,基数可以是2(二进制转换)到36之间的数字。如果基数大于10,则“9”之后的下一个数字将是字母“a”。

     

如果基数为10且val为负数,则前缀为减号。

     

itoa()函数返回作为s传递的指针。

您不希望使用n+1作为基数。

答案 2 :(得分:1)

  

成功时函数返回0或   -1在溢出的情况下(编码我需要一个大于n的缓冲区)。

然而你没有这样做。

  

int j = 0;

这是为了什么?

  

s = itoa(i,s,n + 1);

你为什么要分配给s?

  

我尝试了一些不同的变化   从

     

* s = itoa(i); s = itoa(i); s = itoa(i,s,n + 1);

随机尝试,直到你偶然发现一个有效的方法。

在这里分配s或* s是不合适的,并且表明对C的理解不足;我强烈建议获得更多的语言教学。完成后,您可以使用snprintf,例如,

#include <stdio.h>
int bcd_encode(int i, int n, char *s){  
    int r = snprintf(s, n, "%d", i);
    return r < n? 0 : -1;  
}

假设s应该是NUL终止的并且n包含NUL - 那些细节没有在你的描述中指定。

顺便说一下,这不是“BCD”的意思 - 见http://en.wikipedia.org/wiki/Binary-coded_decimal

答案 3 :(得分:0)

itoa()未定义意味着您缺少头文件

 #include < stdlib.h> 

如果没有定义,编译器假定未知函数itoa()返回一个int(由于愚蠢的历史原因)。

始终听编译警告 - 他们是你的朋友!