Passing string by value in C - c

After going through multiple examples of passing a string by value in C, I still don't understand why the following code does not work
int main(void){
char *fileList;
strcpy(fileList,"This is a test line\n");
char type = 'F';
if(checkFileList(fileList, type)){
printf("Proper File list\n");
}
else{
printf("Improper File list\n");
}
}
int checkFileList(char *string, char type){
// Do something with string
}
This program works if I define the variable fileList in the main function as-
char fileList[128];
But I can't provide a fixed size to this string as I get the string only at runtime and hence don't know how long it'll be.
What am I doing wrong here? Please note that I don't want to pass the string by reference as I'll be changing the string in the function and don't want this to be reflected in the original string.

In your code
char *fileList;
strcpy(fileList,"This is a test line\n");
invokes undefined behaviour
, as , fileList is used uninitialized.
You need to allocate memory to fileList before using it. Maybe malloc() and family of functions will help you into that. Also, read about free().
FWIW,
This program works if I define the variable fileList in the main function as-
char fileList[128];
because, the fileList is an array here and the memory allocation is already done by the compiler. So, it is ok to use that.
BTW "Passing string by value" is misuse of the terms. C uses pass-by-value for any function parameter passing.

In order to allocate the memory for the string at runtime you better get to know the size of the string first:
int main(void){
const char *str = "This is a test line\n";
int len = strlen(str);
char *fileList = malloc(len);
// then later you also have to take care for releasing the allocated memory:
free(fileList);
}

Related

Is there a way to safely collect the data from a returned char*?

I am working on a project for fun to learn C programming, and in Java, I know that I can just obtain a String from a method through a simple return statement. However, in C, I believe it is returning the address of the pointer or garbage data. Here is some basic code:
// In Main Method
char *words = getWords();
// ...
// In getWords
char *getWords() {
char *input; //Well-formatted input.
// Filler code that collects data through file or text entry with 256 max char.
char str[256];
scan("%s", str);
input = str;
return input;
}
You need to pass the pointer as an argument and store the data there itself. Declaring local pointer and returning it is not a good way of doing it. It may lead to dangling pointer.
https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/
After further review, I have discovered that this is the problem:
char str[256];
Should be static:
static char str[256];
Now it returns the correct inputted string.

return a string after being concantenated using strcpy and strcat [duplicate]

I haven't used C in over 3 years, I'm pretty rusty on a lot of things.
I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.
Here is my code:
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return word;
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).
Help is appreciated.
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;
}
char word[length];
char *rtnPtr = word;
...
return rtnPtr;
This is not good. You are returning a pointer to an automatic (scoped) variable, which will be destroyed when the function returns. The pointer will be left pointing at a destroyed variable, which will almost certainly produce "strange" results (undefined behaviour).
You should be allocating the string with malloc (e.g. char *rtnPtr = malloc(length)), then freeing it later in main.
You are allocating your string on the stack, and then returning a pointer to it. When your function returns, any stack allocations become invalid; the pointer now points to a region on the stack that is likely to be overwritten the next time a function is called.
In order to do what you're trying to do, you need to do one of the following:
Allocate memory on the heap using malloc or similar, then return that pointer. The caller will then need to call free when it is done with the memory.
Allocate the string on the stack in the calling function (the one that will be using the string), and pass a pointer in to the function to put the string into. During the entire call to the calling function, data on its stack is valid; its only once you return that stack allocated space becomes used by something else.
Your pointer is pointing to local variable of the function. So as soon as you return from the function, memory gets deallocated. You have to assign memory on heap in order to use it in other functions.
Instead
char *rtnPtr = word;
do this
char *rtnPtr = malloc(length);
So that it is available in the main function. After it is used free the memory.
As others already said, you can't return a non-constant string in a useful way without allocating it on the heap (e.g. using strdup). But in all recent versions of the C standard (C89 and later if I'm not mistaken) you can return a struct. It won't be necessary for the caller to deallocate the result because it's not on the heap. And it's thread-safe.
#include <stdio.h>
struct stringbuf
{
char buf[40];
};
struct stringbuf getanswer(int i)
{
struct stringbuf result = { 0 };
snprintf(result.buf, sizeof(result.buf), "The answer is %d", i);
return result;
}
int main(int argc, char **argv)
{
/*
* Remember to pass the .buf member, not the struct, to functions
* such as printf which expect a character pointer as argument!
* Passing the result of getanswer in the next line without .buf
* appended, will likely crash the program because the program
* will put the entire struct on the stack, not a character
* pointer, and will make printf interpret the first few bytes
* of the string as a pointer. That would be bad.
*/
printf("How many arguments did I get? %s\n", getanswer(argc).buf);
return 0;
}
Note: To keep the sample code as simple and focused as possible, I simply declared a struct type without typedef. You may save yourself a lot of typing by using typedef and returning the defined type.
There are (arguably) a few disadvantages:
A function that returns a struct cannot return NULL.
The size of the buffer in the struct is fixed because the compiler has to know the size of the return type at compile time.
The result of a function that returns a struct is probably stored on the stack; this may be a problem in small systems (like microcontrollers) that don't have a lot of stack space.
Unlike character arrays, an instance of a struct is not a usable alias for the string that's stored in it. In other words, whereas you can create an array of characters and use its name as a pointer to the first character, you can't use the name of a struct as a pointer.
That last point is important because you have to keep in mind that a struct with a character array is not the same as the array itself. So if you want to call a string function, you should pass the string member variable, not a pointer to the struct. This is especially important for functions with variadic arguments such as printf and friends where a compiler may not warn you if you're doing it wrong: passing a struct will place the entire struct on the stack, not just a pointer to the first character. Printf will interpret the first few characters in the struct as a character pointer, which will certainly be invalid.
Yes, it's possible to cast a pointer to a struct to a char * and pass it to a string function (including printf) and that will work correctly, but I would argue that it's bad practice to do this: If you (or someone else) ever decides to put another member variable in the struct declaration in front of the string buffer, any use of a typecast pointer to a struct that assumes that the string buffer starts where the struct starts, would silently fail. You probably want to avoid this, so use a pointer to the string member variable even if it's somewhat inconvenient.
===Jac
word is on the stack and goes out of scope as soon as getStr() returns. You are invoking undefined behavior.
I came across this thread while working on my understanding of Cython. My extension to the original question might be of use to others working at the C / Cython interface. So this is the extension of the original question: how do I return a string from a C function, making it available to Cython & thus to Python?
For those not familiar with it, Cython allows you to statically type Python code that you need to speed up. So the process is, enjoy writing Python :), find its a bit slow somewhere, profile it, calve off a function or two and cythonize them. Wow. Close to C speed (it compiles to C) Fixed. Yay. The other use is importing C functions or libraries into Python as done here.
This will print a string and return the same or another string to Python. There are 3 files, the c file c_hello.c, the cython file sayhello.pyx, and the cython setup file sayhello.pyx. When they are compiled using python setup.py build_ext --inplace they generate a shared library file that can be imported into python or ipython and the function sayhello.hello run.
c_hello.c
#include <stdio.h>
char *c_hello() {
char *mystr = "Hello World!\n";
return mystr;
// return "this string"; // alterative
}
sayhello.pyx
cdef extern from "c_hello.c":
cdef char* c_hello()
def hello():
return c_hello()
setup.py
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Easier still: return a pointer to a string that's been malloc'd with strdup.
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return strdup(&word[0]);
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}

Passing string from function to another string C [duplicate]

I haven't used C in over 3 years, I'm pretty rusty on a lot of things.
I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.
Here is my code:
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return word;
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).
Help is appreciated.
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;
}
char word[length];
char *rtnPtr = word;
...
return rtnPtr;
This is not good. You are returning a pointer to an automatic (scoped) variable, which will be destroyed when the function returns. The pointer will be left pointing at a destroyed variable, which will almost certainly produce "strange" results (undefined behaviour).
You should be allocating the string with malloc (e.g. char *rtnPtr = malloc(length)), then freeing it later in main.
You are allocating your string on the stack, and then returning a pointer to it. When your function returns, any stack allocations become invalid; the pointer now points to a region on the stack that is likely to be overwritten the next time a function is called.
In order to do what you're trying to do, you need to do one of the following:
Allocate memory on the heap using malloc or similar, then return that pointer. The caller will then need to call free when it is done with the memory.
Allocate the string on the stack in the calling function (the one that will be using the string), and pass a pointer in to the function to put the string into. During the entire call to the calling function, data on its stack is valid; its only once you return that stack allocated space becomes used by something else.
Your pointer is pointing to local variable of the function. So as soon as you return from the function, memory gets deallocated. You have to assign memory on heap in order to use it in other functions.
Instead
char *rtnPtr = word;
do this
char *rtnPtr = malloc(length);
So that it is available in the main function. After it is used free the memory.
As others already said, you can't return a non-constant string in a useful way without allocating it on the heap (e.g. using strdup). But in all recent versions of the C standard (C89 and later if I'm not mistaken) you can return a struct. It won't be necessary for the caller to deallocate the result because it's not on the heap. And it's thread-safe.
#include <stdio.h>
struct stringbuf
{
char buf[40];
};
struct stringbuf getanswer(int i)
{
struct stringbuf result = { 0 };
snprintf(result.buf, sizeof(result.buf), "The answer is %d", i);
return result;
}
int main(int argc, char **argv)
{
/*
* Remember to pass the .buf member, not the struct, to functions
* such as printf which expect a character pointer as argument!
* Passing the result of getanswer in the next line without .buf
* appended, will likely crash the program because the program
* will put the entire struct on the stack, not a character
* pointer, and will make printf interpret the first few bytes
* of the string as a pointer. That would be bad.
*/
printf("How many arguments did I get? %s\n", getanswer(argc).buf);
return 0;
}
Note: To keep the sample code as simple and focused as possible, I simply declared a struct type without typedef. You may save yourself a lot of typing by using typedef and returning the defined type.
There are (arguably) a few disadvantages:
A function that returns a struct cannot return NULL.
The size of the buffer in the struct is fixed because the compiler has to know the size of the return type at compile time.
The result of a function that returns a struct is probably stored on the stack; this may be a problem in small systems (like microcontrollers) that don't have a lot of stack space.
Unlike character arrays, an instance of a struct is not a usable alias for the string that's stored in it. In other words, whereas you can create an array of characters and use its name as a pointer to the first character, you can't use the name of a struct as a pointer.
That last point is important because you have to keep in mind that a struct with a character array is not the same as the array itself. So if you want to call a string function, you should pass the string member variable, not a pointer to the struct. This is especially important for functions with variadic arguments such as printf and friends where a compiler may not warn you if you're doing it wrong: passing a struct will place the entire struct on the stack, not just a pointer to the first character. Printf will interpret the first few characters in the struct as a character pointer, which will certainly be invalid.
Yes, it's possible to cast a pointer to a struct to a char * and pass it to a string function (including printf) and that will work correctly, but I would argue that it's bad practice to do this: If you (or someone else) ever decides to put another member variable in the struct declaration in front of the string buffer, any use of a typecast pointer to a struct that assumes that the string buffer starts where the struct starts, would silently fail. You probably want to avoid this, so use a pointer to the string member variable even if it's somewhat inconvenient.
===Jac
word is on the stack and goes out of scope as soon as getStr() returns. You are invoking undefined behavior.
I came across this thread while working on my understanding of Cython. My extension to the original question might be of use to others working at the C / Cython interface. So this is the extension of the original question: how do I return a string from a C function, making it available to Cython & thus to Python?
For those not familiar with it, Cython allows you to statically type Python code that you need to speed up. So the process is, enjoy writing Python :), find its a bit slow somewhere, profile it, calve off a function or two and cythonize them. Wow. Close to C speed (it compiles to C) Fixed. Yay. The other use is importing C functions or libraries into Python as done here.
This will print a string and return the same or another string to Python. There are 3 files, the c file c_hello.c, the cython file sayhello.pyx, and the cython setup file sayhello.pyx. When they are compiled using python setup.py build_ext --inplace they generate a shared library file that can be imported into python or ipython and the function sayhello.hello run.
c_hello.c
#include <stdio.h>
char *c_hello() {
char *mystr = "Hello World!\n";
return mystr;
// return "this string"; // alterative
}
sayhello.pyx
cdef extern from "c_hello.c":
cdef char* c_hello()
def hello():
return c_hello()
setup.py
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Easier still: return a pointer to a string that's been malloc'd with strdup.
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return strdup(&word[0]);
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}

Returing and printing a string from a function in C

I am trying to return and print a function in C. Printing it out works in the function just fine, but when I try to print it after returning it from the function, I get nonsense.
I have already tried a lot and I think I have seen at least 6 stack overflow posts similar to this and this is the closest thing I can get to working that is not a segmentation fault or an error.
Code:
char* getBitstring(unsigned short int instr) {
//this is what the code below is going to convert into. It is set to default
//as a 16 bit string full of zeros to act as a safety default.
char binaryNumber[] = "0000000000000000";
//....
//doing things to binaryNumber
//.....
printf("don't get excited yet %s\n", binaryNumber); //note, this works
return binaryNumber;
}
int main(int argc, char *argv[]) {
char *a = getBitstring(0x1234);
printf("%s", a); //this fails
return 0;
}
Here is the output:
don't get excited yet 0001001000110100
������e��r�S�����$�r�#�t�$�r�����ͅS�������t����
This is because you are returning a pointer to an object allocated in automatic memory - an undefined behavior.
If you want to return a string from a function, you need to return either a dynamically-allocated block, or a statically allocated block.
Another choice is to pass the buffer into the function, and provide the length as the return value of the function, in the way the file reading functions do it:
size_t getBitstring(unsigned short int instr, char* buf, size_t buf_size) {
... // Fill in the buffer without going over buf_size
printf("don't get excited yet %s\n", binaryNumber);
return strlen(buf);
}
Here is how you call this function:
char binaryNumber[] = "0000000000000000";
size_t len = getBitstring(instr, binaryNumber, sizeof(binaryNumber));
Now binaryNumber is an automatic variable in the context of the caller, so the memory would be around while the caller needs it.
This is a good example of a problem people hit when they're learning C that they probably wouldn't hit if they were operating in Java or another more modern language that doesn't expose the details of memory layout to the user.
While everyone's answer here is probably technically correct, I'm going to try a different tack to see if I can answer your question without just giving you a line of code that will fix it.
First you need to understand what's going on when returning a
variable defined inside a function, like this:
void f(void) {
int x = 0;
/* do some crazy stuff with x */
return x;
}
What happens when you call return x;? I'm probably omitting some
details here, but what is essentially going on is that the calling
context gets the value stored inside the variable named x at
that time. The storage that is allocated to store that value is
no longer guaranteed to contain that value after the function is
over.
Second, we need to understand what happens when we refer to an array
by its name. Say we have a 'string':
char A[] = "12345";
In C, this is actually equivalent to declaring an array of
characters that ends in a \0:
char A[6] = { '1' , '2' , '3' , '4' , '5' , '\0' };
Then this is sort of like declaring six chars A[0], A[1], ...
, A[5]. The variable A is actually of type char * i.e. it is a
pointer containing the memory address storing A[0] (the beginning
of the array).
Finally, we need to understand what happens when you call printf to
print a string like this:
printf("%s", A);
What you're saying here is "print all the bytes starting at memory
address A until you hit a byte that contains \0".
So, let's put it all together. When you run your code, the variable binaryNumber is a pointer containing the memory address of the first character of the array: binaryNumber[0], and this address is what's returned by the function. BUT, you've declared the array inside of getBitString, so as we know that the memory allocated for the array is no longer guaranteed to store the same values after getBitString is over.
When you run printf("%s", a) you're telling C to "print all the bytes starting at memory address a until you get to a byte containing \0 -- but since that memory address is only guaranteed to contain valid values inside getBitString, what you get is whatever garbage it happens to contain at the time when you call it outside of getBitString.
So what can you do to resolve the problem? Well you have several options, here are is a (non-exhaustive) list:
You declare binaryString outside of getBitString so that it's still valid when you try to access it in main
You declare binaryString as static as some others have suggested, which is effectively the same thing as above, except that the actual variable name binaryString is only valid inside the function, but the memory allocated to store the array is still valid outside the function.
You make a copy of the string using the strdup() function before you return it in your function. Remember that if you do this, you have to free() the pointer returned by strdup() after you're done with it, otherwise what you've got is a memory leak.
Your binaryNumber character array only exists inside of your getBitstring function. Once that function returns, that memory is no longer allocated to your binaryNumber. To keep that memory allocated for use outside of that function you can do one of two things:
Return a dynamically allocated array
char* getBitstring(unsigned short int instr) {
// dynamically allocate array to hold 16 characters (+1 null terminator)
char* binaryNumber = malloc(17 * sizeof(char));
memset(binaryNumber, '0', 16); // Set the first 16 array elements to '0'
binaryNumber[16] = '\0'; // null terminate the string
//....
//doing things to binaryNumber
//.....
return binaryNumber;
}
int main(int argc, char *argv[]) {
char *a = getBitstring(0x1234);
printf("%s", a);
free(a); // Need to free memory, because you dynamically allocated it
return 0;
}
or pass the array into the function as an argument
void* getBitstring(unsigned short int instr, char* binaryNumber, unsigned int arraySize ) {
//....
//doing things to binaryNumber (use arraySize)
//.....
}
int main(int argc, char *argv[]) {
char binaryNumber[] = "0000000000000000";
getBitstring(0x1234, binaryNumber, 16); // You must pass the size of the array
printf("%s", binaryNumber);
return 0;
}
Others have suggested making your binaryNumber array static for a quick fix. This would work, but I would avoid this solution, as it is unnecessary and has other side effects.
Create your return type in dynamic way with malloc() function. create 16+1 blocks for end of string. this is not safe but easy to understand.
char * binaryNumber = (char*) malloc(17*sizeof(char));//create dynamic char sequence
strcpy(binaryNumber,"0000000000000000");//assign the default value with String copy
The final result will be;
char* getBitstring(unsigned short int instr) {
//this is what the code below is going to convert into. It is set to default
//as a 16 bit string full of zeros to act as a safety default.
char * binaryNumber = (char*) malloc(17*sizeof(char));//create dynamic char sequence
strcpy(binaryNumber,"0000000000000000");//assign the default value with String copy function
//....
//doing things to binaryNumber
//.....
printf("don't get excited yet %s\n", binaryNumber); //note, this works
return binaryNumber;
}
int main(int argc, char *argv[]) {
char *a = getBitstring(0x1234);
printf("%s", a); //this fails
return 0;
}
of course include the <string.h> library.
your char binaryNumber[] is local to the function getBitstring(). you cannot return a local variable to other function.
The scope of binaryNumber is over when getBitstring() finishes execution. So, in your main(), char *a is not initialized.
The workaround:
define the array as static so that it does not go out-of-scope. [Not a good approach, but works]
or
use dynamic memory allocation and return the pointer. [don't forget to free later, to avoid memory leak.]
IMO, the second approach is way better.
You need static:
static char binaryNumber[] = "0000000000000000";
Without static keyword, the value of automatic variable is lost after function returns. Probably you know this.

Copy a word from a function to a string with strcpy in C?

I'm in a basic C programming course and I'm trying to create a hangman game. I've been stuck with a problem for the last three hours and I'm not getting any wiser.
Basically, I've created a function which reads a random line from a text file and then copies it to a string. Afterwards, I want to copy that string to another string outside off the function. This is because the main game is supposed to be completely built with functions.
This is the function that reads a random word from the text file and copies it to a string:
char datorns_val()
{
char ordlista[20];
char valt_ord[20];
int raknare = 0;
srand(time(NULL));
random = rand()%10+0;
ptr_file =fopen("hangman.txt","r");
if (!ptr_file)
{
return 1;
}
while (fgets(ordlista,20, ptr_file)!=NULL)
{
raknare++;
if (raknare == random)
strcpy(valt_ord, ordlista);
}
return valt_ord;
}
After this is done, I want to copy the word located in valt_ord to another string, and that's when I'm unsure about what to do:
char word[20];
strcpy(word,datorns_val());
I'm getting two errors that says:
Invalid conversion from 'char' to 'const char*'
and
initializing argument 2 of 'char* strcpy(char*, const char*)'
Am I on the right track here with using strcpy() twice or am I completely lost? I tried my build without a function structure and simply typing out all the code on after another and it works, if a replace the second strcpy() with a simple char word = valt_ord.
Thanks, Jonathan
(Sorry if my code is hard to understand, I'm swedish and my second language is English)
Currently you're returning a character, which is not of much use, since you need a string that will outlive the function which creates it. You should return a dynamically allocated string (using a pointer) for this.
char* datorns_val()
{
// ... your current code
char *ret_str = malloc(20);
strcpy(ret_str, valt_ord);
return ret_str;
}
At the end where you use it, you should free it when done.
char *result = datorns_val();
// use result
free(result);
result = NULL;
Alternatively, if you're sure that the function which is calling the datorns_val is the only one which is going to use the result, then I'd recommend something else which doesn't involve dynamic memory alloc/decalloc (malloc/free). Pass the string to be loaded to datorns_val.
int datorns_val(char (*str_ptr)[20]) // pointer to an array of 20 chars
{
// use str_ptr after dereferencing it to get back the char array
// say you want to copy "abc" to it
strcpy(*str_ptr, "abc");
return 0; // to denote success, you may return -1 for failure
}
// caller's end
char result[20] = "";
int success = datorns_val(&result); // pass the array by reference
Read more about arrays and pointers to know more about them.
Your function datorns_val is declared to return char while in fact it returns valt_ord that is of type char[]. Also there is a way bigger problem valt_ord is a local variable so even if you change the declaration the code will not work. You will need to allocate valt_ord dynamically(using malloc) or to pass it as function argument.
argument 2 of strcpy needed string but your function returning char.
man strcpy.
you trying to return local variable, it will be destroyed when you move out of function because it stores the data in stack. Use malloc
see this SO question for further clarification

Resources