gpt4 book ai didi

c - 从函数返回 C 字符串

转载 作者:太空狗 更新时间:2023-10-29 16:14:54 25 4
gpt4 key购买 nike

我试图从函数返回一个 C 字符串,但它不起作用。这是我的代码。

char myFunction()
{
return "My String";
}

main我这样称呼它:
int main()
{
printf("%s", myFunction());
}

我也为 myFunction 尝试了其他一些方法,但它们不起作用。例如:
char myFunction()
{
char array[] = "my string";
return array;
}

注意:我不允许使用指针!

关于这个问题的小背景:

有找出它是哪个月的功能。例如,如果它是 1,那么它返回一月,等等。

所以当它要打印时,它是这样做的: printf("Month: %s",calculateMonth(month)); .现在的问题是如何从 calculateMonth 返回该字符串功能。

最佳答案

您的函数签名需要是:

const char * myFunction()
{
return "my String";
}
背景:
它是 C 和 C++ 的基础,但应该有更多的讨论。
在 C(与 C++ 相关)中,字符串只是一个以零字节结尾的字节数组 - 因此术语“字符串零”用于表示字符串的这种特殊风格。还有其他种类的字符串,但在 C(& C++)中,这种风格由语言本身固有地理解。其他语言(Java、Pascal 等)使用不同的方法来理解 "my string" .
如果您曾经使用过 Windows API(在 C++ 中),您会经常看到诸如“LPCSTR lpszName”之类的函数参数。 'sz' 部分代表了这个 'string-zero' 的概念:一个带有空 (/zero) 终止符的字节数组。
澄清:
为了这个“介绍”,我交替使用“字节”和“字符”这个词,因为这样更容易学习。请注意,还有其他方法(宽字符和多字节字符系统 (mbcs))用于处理国际字符。 UTF-8是 mbcs 的一个例子。为了介绍,我悄悄地“跳过”了所有这些。
内存:
这意味着像 "my string" 这样的字符串实际上使用 9+1 (=10!) 个字节。当您最终开始动态分配字符串时,了解这一点很重要。
所以,如果没有这个“终止零”,你就没有字符串。您有一个字符数组(也称为缓冲区)在内存中徘徊。
数据生命周期:
函数的使用方式是这样的:
const char * myFunction()
{
return "my String";
}

int main()
{
const char* szSomeString = myFunction(); // Fraught with problems
printf("%s", szSomeString);
}
...通常会让您遇到随机未处理的异常/段错误等,尤其是“在路上”。
简而言之,尽管我的回答是正确的 - 10 次中有 9 次你最终会遇到一个程序崩溃,如果你这样使用它,特别是如果你认为这样做是“好习惯”的话。简而言之:通常不是。
例如,想象在 future 的某个时间,字符串现在需要以某种方式进行操作。通常,编码人员会“走简单的道路”并(尝试)编写如下代码:
const char * myFunction(const char* name)
{
char szBuffer[255];
snprintf(szBuffer, sizeof(szBuffer), "Hi %s", name);
return szBuffer;
}
也就是说,你的程序会因为编译器(可能/可能不会)释放了 szBuffer 使用的内存而崩溃。到时候 printf()main()被称为。 (你的编译器也应该事先警告你这些问题。)
有两种方法可以返回不会那么容易呕吐的字符串。
  • 返回存在一段时间的缓冲区(静态或动态分配)。在 C++ 中,使用“辅助类”(例如, std::string )来处理数据的生命周期(这需要更改函数的返回值),或
  • 将缓冲区传递给填充信息的函数。

  • 请注意,在 C 中不使用指针是不可能使用字符串的。正如我所展示的,它们是同义词。即使在带有模板类的 C++ 中,也总是在后台使用缓冲区(即指针)。
    所以,为了更好地回答(现在修改的问题)。 (肯定会提供各种“其他答案”。)
    更安全的答案:
    示例 1,使用静态分配的字符串:
    const char* calculateMonth(int month)
    {
    static char* months[] = {"Jan", "Feb", "Mar" .... };
    static char badFood[] = "Unknown";
    if (month < 1 || month > 12)
    return badFood; // Choose whatever is appropriate for bad input. Crashing is never appropriate however.
    else
    return months[month-1];
    }

    int main()
    {
    printf("%s", calculateMonth(2)); // Prints "Feb"
    }
    什么 static在这里(许多程序员不喜欢这种类型的“分配”)是将字符串放入程序的数据段中。也就是说,它是永久分配的。
    如果您转向 C++,您将使用类似的策略:
    class Foo
    {
    char _someData[12];
    public:
    const char* someFunction() const
    { // The final 'const' is to let the compiler know that nothing is changed in the class when this function is called.
    return _someData;
    }
    }
    ...但使用辅助类可能更容易,例如 std::string ,如果您正在编写供自己使用的代码(而不是与他人共享的库的一部分)。
    示例 2,使用调用者定义的缓冲区:
    这是传递字符串的更“万无一失”的方式。返回的数据不受调用方的操纵。也就是说,示例 1 很容易被调用方滥用,并使您面临应用程序故障。这样,它更安全(尽管使用了更多的代码行):
    void calculateMonth(int month, char* pszMonth, int buffersize)
    {
    const char* months[] = {"Jan", "Feb", "Mar" .... }; // Allocated dynamically during the function call. (Can be inefficient with a bad compiler)
    if (!pszMonth || buffersize<1)
    return; // Bad input. Let junk deal with junk data.
    if (month<1 || month>12)
    {
    *pszMonth = '\0'; // Return an 'empty' string
    // OR: strncpy(pszMonth, "Bad Month", buffersize-1);
    }
    else
    {
    strncpy(pszMonth, months[month-1], buffersize-1);
    }
    pszMonth[buffersize-1] = '\0'; // Ensure a valid terminating zero! Many people forget this!
    }

    int main()
    {
    char month[16]; // 16 bytes allocated here on the stack.
    calculateMonth(3, month, sizeof(month));
    printf("%s", month); // Prints "Mar"
    }
    第二种方法更好的原因有很多,特别是如果您正在编写供其他人使用的库(您不需要锁定特定的分配/释放方案,第三方无法破坏您的代码,并且您不需要链接到特定的内存管理库),但与所有代码一样,您最喜欢什么取决于您。出于这个原因,大多数人选择示例 1,直到他们被烧毁了太多次以至于他们拒绝再这样写了 ;)
    免责声明:
    几年前我退休了,我的 C 现在有点生疏了。这个演示代码应该都可以用 C 正确编译(不过对于任何 C++ 编译器都可以)。

    关于c - 从函数返回 C 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1496313/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com