通过函数传递的 char* 不打印任何内容
char* passed through function prints nothing
这是我第一次在这里发帖:)
我试过在这里搜索,但没有找到我的具体问题的答案。
我对 C 很陌生,到目前为止主要使用 C#,
所以整个指针的想法不是我的小菜一碟..
我试图创建一个将整数转换为字符串的函数,
我成功了,直到返回值的部分..
我不明白为什么在函数末尾可以正确打印字符串,但在 main 函数中却不是这样。如果有人可以看一下代码并向我解释为什么它不起作用(为什么它在 main 函数中什么都不打印),我们将不胜感激。
主要功能:
int main()
{
printf("%s", int_to_string(4058));
return 0;
};
整型转字符串函数:
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;
};
Sub-Func - 整数长度函数:
int int_length(int s)
{
int count = 0;
while(s != 0)
{
count++;
s /= 10;
}
return count;
};
非常感谢您的帮助!
您正在返回局部变量的地址,即 str
。一旦函数退出,该地址就不再有效。尝试取消引用该地址调用 undefined behavior.
您应该更改您的函数以将 str
声明为 static
,以便它的生命周期在函数退出后存在。在这种情况下,您需要将数组设为固定大小,因此它至少为 12 个字节,这应该足够大以容纳 32 位 int
.
的字符串表示形式
您的程序的主要问题是您返回了对自动字符数组的引用。这意味着数组在函数 returns 之后是死的,因此在 main 函数中不可访问。您可以阅读有关变量范围的更多信息以更好地理解这一点。
目前,您有两种方法可以解决此问题。
使用堆 - 您可以使用 malloc
函数在堆上分配一个字符数组。保证在堆上分配的任何内存都在范围内,直到程序退出或明确释放为止。
因此,您可以将数组声明更改为 -
char *str = malloc(len+1); //As suggested by BLUEPIXY size needs to be len+1 to accomodate the [=10=]
有了这个,你还必须记住在使用完后释放分配的内存。所以在 main 中你将不得不更改为
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
returns.
时自动超出范围
也与您的问题无关,您的代码存在致命错误。你不是 null 终止你的字符串。当使用 %s
格式字符串修饰符传递给 printf
时,这将导致未定义的行为。
所以一个简单的修复是
str[count] = '[=14=]';
就在函数的末尾。
希望对您有所帮助。
这是我第一次在这里发帖:) 我试过在这里搜索,但没有找到我的具体问题的答案。 我对 C 很陌生,到目前为止主要使用 C#, 所以整个指针的想法不是我的小菜一碟..
我试图创建一个将整数转换为字符串的函数, 我成功了,直到返回值的部分.. 我不明白为什么在函数末尾可以正确打印字符串,但在 main 函数中却不是这样。如果有人可以看一下代码并向我解释为什么它不起作用(为什么它在 main 函数中什么都不打印),我们将不胜感激。
主要功能:
int main()
{
printf("%s", int_to_string(4058));
return 0;
};
整型转字符串函数:
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;
};
Sub-Func - 整数长度函数:
int int_length(int s)
{
int count = 0;
while(s != 0)
{
count++;
s /= 10;
}
return count;
};
非常感谢您的帮助!
您正在返回局部变量的地址,即 str
。一旦函数退出,该地址就不再有效。尝试取消引用该地址调用 undefined behavior.
您应该更改您的函数以将 str
声明为 static
,以便它的生命周期在函数退出后存在。在这种情况下,您需要将数组设为固定大小,因此它至少为 12 个字节,这应该足够大以容纳 32 位 int
.
您的程序的主要问题是您返回了对自动字符数组的引用。这意味着数组在函数 returns 之后是死的,因此在 main 函数中不可访问。您可以阅读有关变量范围的更多信息以更好地理解这一点。
目前,您有两种方法可以解决此问题。
使用堆 - 您可以使用
malloc
函数在堆上分配一个字符数组。保证在堆上分配的任何内存都在范围内,直到程序退出或明确释放为止。 因此,您可以将数组声明更改为 -char *str = malloc(len+1); //As suggested by BLUEPIXY size needs to be len+1 to accomodate the [=10=]
有了这个,你还必须记住在使用完后释放分配的内存。所以在 main 中你将不得不更改为
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
returns. 时自动超出范围
也与您的问题无关,您的代码存在致命错误。你不是 null 终止你的字符串。当使用 %s
格式字符串修饰符传递给 printf
时,这将导致未定义的行为。
所以一个简单的修复是
str[count] = '[=14=]';
就在函数的末尾。 希望对您有所帮助。