从函数返回C字符串 [英] Returning C string from a function

查看:101
本文介绍了从函数返回C字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个函数返回C字符串,但它不工作。这里是我的code。

I am trying to return a C string from a function but its not working. Here is my code.

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

在主我打电话这样的:

int main()
{
  printf("%s",myFunction());
}

我也试过 myFunction的一些其他的方式,但他们没有工作。例如:

I have also tried some other ways for myFunction but they are not working. E.g:

char myFunction()
{
  char array[] = "my string";
  return array;
}

请注意:我不允许使​​用指针

Note: I am not allowed to use pointers!

在这个问题上一点背景:
有哪些是找出它是哪个例如每月功能;如果1再寄回一月等等等等。

Little background on this problem: There is function which is finding out which month it is e.g; if its 1 then it return January etc etc.

所以当它去打印,它做这个样子。 的printf(月:%S,calculateMonth(月)); 。现在的问题是如何返回从 calculateMonth 函数的字符串。

So when its going to print, it's doing like this. printf("Month: %s",calculateMonth(month));. Now the problem is how to return that string from the calculateMonth function.

推荐答案

你的函数的签名必须是:

your function signature needs to be:

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

编辑:

背景:

它以来这个职位和功放年;从来没有想到会被否决了,因为它是如此根本,以C&放大器; C ++。尽管如此,多一点讨论,应该是为了。

It's been years since this post & never thought it would be voted up, because it's so fundamental to C & C++. Nevertheless, a little more discussion should be in order.

在C(和C ++的这个问题),一个字符串就是一个零终止byte--因此称为串零字节数组用于重新present字符串这个特殊的味道。还有其它种类的字符串,但在C(和C ++),此风味固有由语言本身的理解。其他语言(Java,帕斯卡等)使用不同的方法来了解我的字符串。

In C (& C++ for that matter), a string is just an array of bytes terminated with a zero byte-- hence the term "string-zero" is used to represent this particular flavour of string. There are other kinds of strings, but in C (& C++), this flavour is inherently understood by the language itself. Other languages (Java, Pascal, etc) use different methodologies to understand "my string".

如果你曾经使用Windows API(这是在C ++),你会看到相当定期的功能参数,如:LPCSTR lpszName。在'深圳'的一部分重新presents这个概念的字符串零:字节数组与空(/零)终止

If you ever use the Windows API (which is in C++), you'll see quite regularly function parameters like: "LPCSTR lpszName". The 'sz' part represents this notion of 'string-zero': an array of bytes with a null (/zero) terminator.

澄清:

有关这个'前奏',我用这个词字节和着想人物的交替,因为它更容易学习这种方式。要知道,还有其它方法(宽字符和多字节字符系统 - MBCS),用于应付国际字符。 UTF-8是一个MBCS的一个例子。对于介绍的缘故,我悄悄地跳过了这一切。

For the sake of this 'intro', I use the word 'bytes' and 'characters' interchangeably, because it's easier to learn this way. Be aware that there are other methods (wide-characters, and multi-byte character systems--mbcs) that are used to cope with international characters. UTF-8 is an example of a mbcs. For the sake of intro, I quietly 'skip over' all of this.

内存:

这意味着,像我的字符串的字符串实际上使用9 + 1(= 10!)个字节。这是重要的是知道,当你终于得到解决,以动态分配的字符串。
所以,如果没有这个'终止零',你没有一个字符串。你必须在内存中徘徊的字符(也称为缓冲)的数组。

What this means is that a string like "my string" actually uses 9+1 (=10!) bytes. This is important to know when you finally get around to allocating strings dynamically. So, without this 'terminating zero', you don't have a string. You have an array of characters (also called a buffer) hanging around in memory.

数据长寿:

在上面的例子中,实际数据不可长 - 优化编译器将看到数据将被压入堆栈,然后弹出的的printf()电话。因此,任何试图使用的功能是这样的:

In the above example, the actual data isn't available for long -- the optimising compiler will see that the data will be pushed onto a stack and then popped after the printf() call. So, any attempt to use the function this way:

const char * myFunction()
{
    return "My String";
}
int main() 
{
    const char* szSomeString = myFunction(); // fraught with problems
    printf("%s", szSomeString);
}

...一般会降落在你随机未处理的异常/段故障等等。也就是说,你的程序会崩溃,因为编译器(可以/不可以)已经发布了由使用的内存myFunction的()的时间的printf() 被调用。 (编译器也应提醒你这样的问题事先)。

... will generally land you with random unhandled-exceptions/segment faults and the like. That is, your program will crash because the compiler (may/may not) have released the memory used by myFunction() by the time printf() is called. (Your compiler should also warn you of such problems beforehand).

总之,虽然我的答案是正确的 - 9次了10年,你会用,如果你使用它的方式崩溃程序结束,尤其是如果你认为这是良好做法做这种方式。简而言之:这通常不是

In short, although my answer is correct -- 9 times out of 10 you'll end up with a program that crashes if you use it that way, especially if you think it's 'good practice' to do it that way. In short: It's generally not.

有两种方式返回,不会BARF这么爽快的字符串。

There are two ways to return strings that won't barf so readily.


    住了一段时间,或
  1. 返回缓冲区(静态或动态分配)

  2. 传递的缓冲区到获取与信息中填写的功能。

请注意,这是不可能的使用字符串而不使用指针在C正如我已经表明,它们是同义的。即使在C ++与模板类,总有缓冲(即指针)在后台使用。

Note that it is impossible to use strings without using pointers in C. As I have shown, they are synonymous. Even in C++ with template classes, there are always buffers (ie pointers) being used in the background.

因此​​,为了更好地回答(今修改问题)。 (有肯定是各种可提供'其他答案'的)。

So, to better answer the (now modified question). (there are sure to be a variety of 'other answers' that can be provided).

1,如使用静态分配的字符串:

eg 1. using statically allocated strings:

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"
}

什么是静态在这里所做的(许多程序员不喜欢这种类型的'分配'的)是琴弦装进程序的数据段。也就是说,它是永久分配。

What the 'static' does here (many programmers do not like this type of 'allocation') is that the strings get put into the data segment of the program. That is, it's permanently allocated.

如果你移动到C ++,你会使用类似的策略:

If you move over to C++ you'll use similar strategies:

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;
    }   
}

2,如来电者使用定义的缓冲区:

eg 2. using caller-defined buffers:

这是围绕字符串传递的更多的'万无一失'的方式。返回的数据是不受由主叫方操作。也就是说,如1可以很容易地通过一个呼叫方滥用,暴露你的应用程序故障。通过这种方式,它是更安全(虽然使用code多行):

This is the more 'fool proof' way of passing strings around. The data returned isn't subject to manipulation by the calling party. That is, eg 1 can easily be abused by a calling party and expose you to application faults. This way, it's much safer (albeit uses more lines of code):

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"
}

有很多原因,第二个方法比较好,特别是如果你正在写被别人使用的库(您不需要锁定到一个特定的分配/释放方案,第三方无法破解您code,你并不需要链接到一个特定的内存管理库),但像所有code,它给你什么,你最喜欢的。出于这个原因,大多数人选择如1,直到他们已经被烧毁,他们拒绝把它写了很多次这样了;)

There are lots of reasons why the 2nd method is better, particularly if you're writing a library to be used by others (you don't need to lock into a particular allocation/deallocation scheme, 3rd parties can't break your code, you don't need to link to a specific memory management library), but like all code, it's up to you on what you like best. For that reason, most people opt for eg 1 until they've been burnt so many times that they refuse to write it that way anymore ;)

免责声明:

我退休好几年回来,我的C现在是一个有点生疏。该演示code都应该用C正确编译(这是确定任何C ++编译器,虽然)。

I retired several years back and my C is a bit rusty now. This demo code should all compile properly with C (it is ok for any C++ compiler though).

这篇关于从函数返回C字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆