通过函数传递的 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 函数中不可访问。您可以阅读有关变量范围的更多信息以更好地理解这一点。

目前,您有两种方法可以解决此问题。

  1. 使用堆 - 您可以使用 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);
    
  2. 在调用者中分配内存 - 如果您不想陷入在堆中分配内存并稍后释放它的混乱局面。您可以在调用者中分配内存并将其作为

    传递给您的函数
    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.

  3. 时自动超出范围

也与您的问题无关,您的代码存在致命错误。你不是 null 终止你的字符串。当使用 %s 格式字符串修饰符传递给 printf 时,这将导致未定义的行为。

所以一个简单的修复是

str[count] = '[=14=]'; 

就在函数的末尾。 希望对您有所帮助。