这是我第一次在这里发帖:) 我试过在这里搜索,但没有找到我的具体问题的答案。 我是C的新手,主要使用C#到现在为止, 所以整个指针的想法不是我的小蛋糕..
我尝试创建一个将整数转换为字符串的函数, 我成功直到返回值的部分.. 我不明白为什么在函数结束时,正确打印字符串,但主函数不是这种情况。如果有人可以查看代码并向我解释为什么它不起作用(为什么它在主函数中没有打印),将不胜感激。
主要功能:
int main()
{
printf("%s", int_to_string(4058));
return 0;
};
Int to String Function:
char* int_to_string(int n)
{
int len = int_length(n);
char str[len];
int count = 1;
while (n != 0)
{
char c = (n % 10) + '0';
str[len - count] = c;
count++;
n /= 10;
}
char* s = str;
printf(s); // Works perfectly, prints the number as a string of characters
return s;
};
子功能 - 内部长度功能:
int int_length(int s)
{
int count = 0;
while(s != 0)
{
count++;
s /= 10;
}
return count;
};
真诚地感谢您的帮助!
答案 0 :(得分:1)
您将返回本地变量的地址,即str
。函数退出后,该地址不再有效。试图取消引用该地址会调用undefined behavior。
您应该更改函数以将str
声明为static
,以便在函数退出后其生命周期存在。在这种情况下,您需要使数组成为固定大小,因此至少要使用12个字节,这应该足以保存32位int
的字符串表示。
答案 1 :(得分:1)
您的程序的主要问题是您正在返回对自动字符数组的引用。这意味着在函数返回后数组已死,因此在main函数中无法访问。您可以阅读有关变量范围的更多信息,以便更好地理解这一点。
目前,您有两种解决此问题的方法。
使用堆 - 您可以使用malloc
函数在堆上分配字符数组。保证堆上分配的任何内存都保持在范围内,直到程序退出或显式释放为止。
因此,您可以将数组声明更改为 -
char *str = malloc(len+1); //As suggested by BLUEPIXY size needs to be len+1 to accomodate the \0
有了这个,你还必须记住在完成使用后释放分配的内存。因此,在主要内容中,您必须更改为
char *str = int_to_string(5098);
printf("%s", str);
free(str);
在调用者中分配内存 - 如果你不想陷入在堆中分配内存并稍后释放它的混乱局面。您可以在调用者中分配内存并将其作为
传递给您的函数char str[len+1]; // Same reasoning as before for len+1
printf("%s", int_to_string(5098, str));
,您的功能将更改为
char* int_to_string(int n, char *str){
// No need to declare str now. Start using as before
...
return str;
}
在这种情况下,您无需担心释放内存,因为当main
返回时它会自动超出范围。
与您的问题无关,您的代码存在致命错误。你不是null终止你的字符串。当使用printf
格式字符串修饰符传递给%s
时,这将导致未定义的行为。
所以一个简单的修复就是
str[count] = '\0';
就在功能的最后。 我希望这会有所帮助。