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

问题描述 投票:1回答:4

我正在研究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);

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

c string type-conversion integer prototype
4个回答
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作为基数。


1
投票
#include <stdlib.h>

如果没有这个,编译器对itoa()一无所知,并假设它返回一个int


1
投票

该函数在成功时返回0或在溢出的情况下返回-1(编码i需要大于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应该以NULL结尾并且包含NULL - 这些细节未在您的描述中指定。

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


0
投票

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

 #include < stdlib.h> 

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

总是听编译器警告 - 他们是你的朋友!

© www.soinside.com 2019 - 2024. All rights reserved.