Either allocate the string on the stack on the caller side and pass it to your function:

void getStr(char *wordd, int length) {
    ...
}

int main(void) {
    char wordd[10 + 1];
    getStr(wordd, sizeof(wordd) - 1);
    ...
}

Or make the string static in getStr:

char *getStr(void) {
    static char wordd[10 + 1];
    ...
    return wordd;
}

Or allocate the string on the heap:

char *getStr(int length) {
    char *wordd = malloc(length + 1);
    ...
    return wordd;
}
Answer from michaelmeyer on Stack Overflow
🌐
The Valley of Code
thevalleyofcode.com › lesson › c-advanced › return-string
C Advanced: Returning strings
The tricky thing is defining the return value type. Strings in C are arrays of char elements, so we can’t really return a string - we must return a pointer to the first element of the string.
🌐
Quora
quora.com › How-do-I-return-a-string-in-C
How to return a string in C - Quora
Answer (1 of 25): Like so: [code]#include char* moo(); int main(int argc, char** argv) { puts(moo()); return 0; } char* moo() { char* out = "cows"; return out; } [/code]
Top answer
1 of 6
11

The methods I've seen most are 2 and 3.

The user supplied buffer is actually quite simple to use:

char buffer[128];
mytype_to_string(mt, buffer, 128);

Though most implementations will return the amount of buffer used.

Option 2 will be slower and is dangerous when using dynamically linked libraries where they may use different runtimes (and different heaps). So you can't free what has been malloced in another library. This then requires a free_string(char*) function to deal with it.

2 of 6
2

I'd echo @ratchet_freak in most cases (maybe with a small tweak for sizeof buffer over 128) but I wanna jump in here with a weirdo response. How about being weird? Why not, besides the problems of getting weird looks from our colleagues and having to be extra persuasive? And I offer this:

// Note allocator parameter.
char* mytype_to_string(allocator* alloc, const mytype_t* t)
{
    char* buf = allocate(alloc, however_much_you_need);
    // fill out buf based on 't' contents
    return buf;
}

And example usage:

void func(my_type a, my_type b)
{
    allocator alloc = allocator_new();
    const char* str1 = mytype_to_string(&alloc, &a);
    if (!str1)
        goto oom;
    const char* str2 = mytype_to_string(&alloc, &b);
    if (!str2)
        goto oom
    // do something with str1 and str2
    goto finish;
oom:
    errno = ENOMEM;
finish:
    // Frees all memory allocated through `alloc`.
    allocator_purge(&alloc);
}

If you did it this way, you can make your allocator very efficient (more efficient than malloc both in terms of allocation/deallocation costs and also improved locality of reference for memory access). It can be an arena allocator that just involves incrementing a pointer in common cases for allocation requests and pool memory in a sequential fashion from large contiguous blocks (with the first block not even requiring a heap allocation -- it can be allocated on the stack). It simplifies error handling. Also, and this might be the most debatable but I think it's practically quite obvious in terms of how it makes it clear to the caller that it's going to allocate memory to the allocator you pass in, requiring explicit freeing (allocator_purge in this case) without having to document such behavior in every single possible function if you use this style consistently. The acceptance of the allocator parameter makes it hopefully quite obvious.

I don't know. I get counter-arguments here like implementing the simplest-possible arena allocator possible (just use maximum alignment for all requests) and dealing with it is too much work. My blunt thought is like, what are we, Python programmers? Might as well use Python if so. Please use Python if these details don't matter. I'm serious. I have had many C programming colleagues who would very likely write not only more correct code but possibly even more efficient with Python since they ignore things like locality of reference while stumbling over bugs they create left and right. I don't see what there is that's so scary about some simple arena allocator here if we are C programmers concerned with things like data locality and optimal instruction selection, and this is arguably much less to think about than at least the types of interfaces that require callers to explicitly free every single individual thing that the interface can return. It offers bulk deallocation over individual deallocation of a sort that's more error-prone. A proper C programmer challenges loopy calls to malloc as I see it, especially when it appears as a hotspot in their profiler. From my standpoint, there has to be more "oomph" to a rationale for still being a C programmer in 2020, and we can't shy away from things like memory allocators anymore.

And this doesn't have the edge cases of allocating a fixed-sized buffer where we allocate, say, 256 bytes and the resulting string is larger. Even if our functions avoid buffer overruns (like with sprintf_s), there's more code to properly recover from such errors that's required which we can omit with the allocator case since it doesn't have those edge cases. We don't have to deal with such cases in the allocator case, unless we truly exhaust the physical addressing space of our hardware (which the above code handles, but it doesn't have to deal with "out of pre-allocated buffer" separately from "out of memory").

Top answer
1 of 15
277

Your function signature needs to be:

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

Background:

It's so fundamental to C & C++, but little more discussion should be in order.

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

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.

Clarification:

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 an mbcs. For the sake of intro, I quietly 'skip over' all of this.

Memory:

This means 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.

Longevity of data:

The use of the function this way:

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

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

... will generally land you with random unhandled-exceptions/segment faults and the like, especially 'down the road'.

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.

For example, imagine some time in the future, the string now needs to be manipulated in some way. Generally, a coder will 'take the easy path' and (try to) write code like this:

const char * myFunction(const char* name)
{
    char szBuffer[255];
    snprintf(szBuffer, sizeof(szBuffer), "Hi %s", name);
    return szBuffer;
}

That is, your program will crash because the compiler (may/may not) have released the memory used by szBuffer by the time the printf() in main() is called. (Your compiler should also warn you of such problems beforehand.)

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

  1. returning buffers (static or dynamically allocated) that live for a while. In C++ use 'helper classes' (for example, std::string) to handle the longevity of data (which requires changing the function's return value), or
  2. pass a buffer to the function that gets filled in with information.

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 (that is, 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.)

Safer Answers:

Example 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.

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

... but it's probably easier to use helper classes, such as std::string, if you're writing the code for your own use (and not part of a library to be shared with others).

Example 2, using caller-defined buffers:

This is the more 'foolproof' way of passing strings around. The data returned isn't subject to manipulation by the calling party. That is, example 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"
}

There are lots of reasons why the second 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, third parties can't break your code, and 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 example 1 until they've been burnt so many times that they refuse to write it that way anymore ;)

Disclaimer:

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).

2 of 15
15

A C string is defined as a pointer to an array of characters.

If you cannot have pointers, by definition you cannot have strings.

🌐
The Valley of Code
thevalleyofcode.com › c-return-string
How to return a string from a C function
The tricky thing is defining the return value type. Strings in C are arrays of char elements, so we can’t really return a string - we must return a pointer to the first element of the string.
🌐
C For Dummies
c-for-dummies.com › blog
Returning a Non-Static String | C For Dummies Blog
It’s possible to return a string created in a function without declaring it static. This trick requires some understanding of how functions return values. Nerd alert! Functions in C return only single values. If you want to return multiple values, you can pack them into a structure or you can pass pointers as arguments.
Find elsewhere
🌐
Sololearn
sololearn.com › en › Discuss › 2567912 › return-string-in-c
Return string in C | Sololearn: Learn to code for FREE!
and a user could then edit the table with arguments, for example changing the delimeter - like this: ./code -d “*:” where in arg behind -d would contain delimeter chosen by user (colon “:”) and then set a new delimeter in edited table to the first character of that argument so -d “*:” would result in a new argument * instead of : new table would look like this after edit: cell1*cell2*cell3 cell4*cell5*cell6 ... And I know that I could avoid problems with function returning string, but I wanted my code to be more readable...
Top answer
1 of 1
1
One note on this: const char* ExampleStringifier(double value, int precision) { char outStr[100] = {0}; sprintf(outStr, "%2.*f", precision, value); return outStr; } outStr is no longer valid after the return statement because it lifetime ends there. The 100 bytes of memory thus can be reused for other variables of other functions. So after some runtime this memory will contain other data which quite likely will not be a string.   You could declare outStr as static which in turn makes the function not longer re-entrant and does not protect against the other issue:   This DebugPrintf("value = %s, another value = %s \n", ExampleStringifier(3.14159265359, 8), ExampleStringifier(1.41421356237, 3)); has the issue, that both calls of ExampleStringifier are executed before the "value = %s, another value = %s \n" is built, and since both calls (might) use the same memory for their outStr location the second call overwrites the first.   Same happens with the string returned from TimeStr().   Side note: the CVI help for gmtime() says this: Note  Per the C89 specification, this function and the localtime function return a pointer to the same static struct tm structure. Using these functions in conjunction with each other might result in overwriting the previous value of the UTCTime parameter. So you see, it's not a "C string" issue but the problem of returning a pointer to a local variable (static or not)   So, my possible solutions: 1) return dynamic allocated memory which the caller has to free() 2) manage an static array of buffers which elements you rotate through with each call 3) require an external buffer and its size to be supplied to the function, it can return a pointer to it
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 50844-return-string-function.html
Return String from a function
Simply declare the function as a char * which would allow you to return a pointer to the desired string. It's been a long time since I've had to return a string from a function so I believe you'd have to either declare the string inside the function as a static char or use dynamic memory allocation ...
🌐
Medium
medium.com › @sandipkumarswain7 › how-to-return-a-string-from-an-user-defined-function-2ac50085d70c
How To Return A String From An User-Defined Function ? | by Sandip Kumar Swain | Medium
June 2, 2021 - Strings in C are arrays of character elements, so we can’t really return a whole string but we can must return a pointer to the first element of the string and then we can access all the elements using the base address
🌐
DaniWeb
daniweb.com › programming › software-development › threads › 56000 › simply-question-how-do-i-return-a-string-from-a-function
Simply question: How do I return a string from a function
Dont return the addr of a local variable since local vars of a function are placed on the stack and are destroyed when the function returns. Better pass the string which you want to be modified to the function. Something like this: #include <stdio.h> #include <string.h> char* my_string (char *src, char* dest); int main() { char str[25] = {'\0'} ; printf("%s\n ",my_string(" in this method ", str)); getchar(); return 0; } char* my_string(char *src, char* dest) { char str1[25] = "How"; char str2[25] = " do I "; char str3[25] = " return a string"; strcat(dest,str1); //append str2 to str and return str strcat(dest,str2); strcat(dest,str3); return dest ; }
🌐
GitHub
gist.github.com › DavidEGrayson › db13d38cbe5c95db64c4
Ways to return a string from a C function · GitHub
Suppose f0 does an expensive calculation and returns a string using option 1, and the other functions f1 through fn each call the previous function in the list to get the string, perform some arbitary operation on it, and then return it using option 1. Each function must call the previous function twice because they don't know an upper bound on the size of the string.
🌐
Sololearn
sololearn.com › en › Discuss › 1159372 › how-do-i-return-a-string-from-a-function-c
How do I return a string from a function? (C++) | Sololearn: Learn to code for FREE!
Alex · + 3 · Sure. string test() { return "test"; } int main() { cout << test(); } 21st Mar 2018, 6:36 PM · Toni Isotalo · + 2 · c != c++ 21st Mar 2018, 11:37 PM · Alex · + 1 · Oh okay it's just this, thank you! 👌 😊 · 21st Mar 2018, 6:39 PM · Lena · + 1 ·
🌐
Unix.com
unix.com › applications › programming
How to pass int and return string in C? - Programming - Unix Linux ...
May 29, 2011 - hi I want to write a function which takes int as input and returns a string like this. char GetString(int iNo) { switch(iNo) { case 0: return "Zero"; break; case 1: return "One"; break; } } void main() { int i; printf("Enter number"); scanf("%d"; i); char str = GetString(i); } but am getting error.
🌐
Reddit
reddit.com › r/cs50 › returning strings in c functions
r/cs50 on Reddit: Returning strings in C functions
April 16, 2023 -

Hello everyone, I'm in Week 2 of CS50 and I've been trying to practice creating user defined functions. So far, I can return integers and floats no problem but I just can't manage to do the same with strings. I've checked online and seen something about 'const char *function_name()' but struggling to follow on from there. Any help would be appreciated.

🌐
Tek-Tips
tek-tips.com › home › forums › software › programmers › languages
return a string from a function | Tek-Tips
May 5, 2008 - If you return a pointer to memory you allocated in a function, you need to remember to free that memory later, so it might be better to pass a pointer into the function along with the size it can store, then you don't have to allocate the memory inside the function. ... #include <stdio.h> #include <string.h> #define STR_SIZE 80 void GetString( char* strOut, unsigned int strSize ) { strncpy( strOut, "Hello World", strSize ); } int main() { char buf[STR_SIZE + 1]; GetString( buf, STR_SIZE ); printf( "%s", buf ); return 0; }
🌐
Rust Programming Language
users.rust-lang.org › t › correct-way-to-implement-a-function-which-returns-a-c-string › 315
Correct way to implement a function which returns a C string - The Rust Programming Language Forum
February 12, 2015 - I would like to implement a function which is exposed as a C function via FFI, returning a C string. What would be the correct memory management model to use? My first try was something along the lines: // In .h extern const char* const get_string(); // In .rs #[no_mangle] pub extern fn get_string() -> *const c_char { let s = String::from_str("Hello!"); let cs = CString::from_slice(s.as_slice().as_bytes()); cs.as_ptr() } But since the lifetime of pointer returned from CString end...