char *传递函数不打印任何内容

时间:2017-07-21 17:49:59

标签: c codelite

这是我第一次在这里发帖:) 我试过在这里搜索,但没有找到我的具体问题的答案。 我是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;
};

真诚地感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您将返回本地变量的地址,即str。函数退出后,该地址不再有效。试图取消引用该地址会调用undefined behavior

您应该更改函数以将str声明为static,以便在函数退出后其生命周期存在。在这种情况下,您需要使数组成为固定大小,因此至少要使用12个字节,这应该足以保存32位int的字符串表示。

答案 1 :(得分:1)

您的程序的主要问题是您正在返回对自动字符数组的引用。这意味着在函数返回后数组已死,因此在main函数中无法访问。您可以阅读有关变量范围的更多信息,以便更好地理解这一点。

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

  1. 使用堆 - 您可以使用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);
    
  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返回时它会自动超出范围。

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

    所以一个简单的修复就是

    str[count] = '\0'; 
    

    就在功能的最后。 我希望这会有所帮助。