Passing string from function to another string C [duplicate] - c

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

Related

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 by value in 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);
}

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.

Using malloc inside a function and return local pointer

Is there any problem in doing something like this in C
char* wrap(char *inp) {
char *newstr;
newstr = (char *)malloc( sizeof(char) * 4);
newstr[0] = 'A';
newstr[1] = inp[0];
newstr[2] = 'B';
newstr[3] = '\0';
return newstr;
}
Basically I want to know that is there problem in using malloc inside a function and returning local variable.
You're not returning a local variable; you're returning the value stored in a local variable.
This code is fine (although the cast on malloc is unnecessary); it's a somewhat common pattern to allocate memory in one function and free it in another.
That's perfect, as long as you're super sure the caller is going to call free to avoid memory leaks .. That's not a big issue on small programs, but when the program gets complex, believe me, you'll be concerned about much more things than freeing a pointer from a supposed-to-be self-contained function ..
But (hands down), there's a much more satisfying solution to this that the standard C Library itself uses. Use a Buffer ! (Claps, Claps)
You know, there is a reason the fgets function for example requires you to provide a character pointer as the first argument, so that it can write to it rather than returning a malloc'd pointer ..
For example ..
#include <ctype.h>
#include <string.h>
void toLower(char *buf, const char *s) {
for(int i = 0; s[i]; ++i)
buf[i] = tolower(s[i]);
}
int main(int argc, const char ** argv) {
const char *s = "ThAt'S a BiG sTrIng";
char lower_version[strlen(s)];
toLower(lower_version, s);
printf("Original Version: %s\nLower Version: %s\n\tTada !\n", s, lower_version);
}
That way, you don't have to worry how you're going to handle the variable in later uses ..
You're leaving this problem to the function caller to deal with.
This is perfectly fine as long as you call free() somewhere to avoid memory leaks. Part of your program design should be defining the "owner" of each pointer. Such ownership can be transferred, so you should keep track of the owner throughout the lifetime of the pointer. The owner at the time the pointer becomes unused should be responsible for calling free().

How do I return a variable size string from a function?

I need a working code for a function that will return a random string with a random length.
What I want to do would be better described by the following code.
char *getRandomString()
{
char word[random-length];
// ...instructions that will fill word with random characters.
return word;
}
void main()
{
char *string = getRandomString();
printf("Random string is: %s\n", string);
}
For this, I am strictly forbidden to use any other include than stdio.h.
Edit: This project will be adapted to be compiled for a PIC Microcontroller, hence I cannot use malloc() or such stuff.
The reason why I use stdio.h here, is for me to be able to inspect the output using GCC.
Currently, this code gives this error.-
“warning: function returns address of local variable [enabled by default]”
Then, I thought this could work.-
char *getRandomString(char *string)
{
char word[random-length];
// ...instructions that will fill word with random characters.
string = word;
return string;
}
void main()
{
char *string = getRandomString(string);
printf("Random string is: %s\n", string);
}
But it only prints a bunch of nonsense characters.
There are three common ways to do this.
Have the caller pass in a pointer to (the first element of) an array into which the data is to be stored, along with a length parameter. If the string to be returned is bigger than the passed-in length, it's an error; you need to decide how to deal with it. (You could truncate the result, or you could return a null pointer. Either way, the caller has to be able to deal with it.)
Return a pointer to a newly allocated object, making it the caller's responsibility to call free when done. Probably return a null pointer if malloc() fails (this is always a possibility, and you should always check for it). Since malloc and free are declared in <stdlib.h> this doesn't meet your (artificial) requirements.
Return a pointer to (the first element of) a static array. This avoids the error of returning a pointer to a locally allocated object, but it has its own drawbacks. It means that later calls will clobber the original result, and it imposes a fixed maximum size.
None if these is an ideal solution.
It points to nonsense characters because you are returning local address. char word[random-length]; is defined local to char *getRandomString(char *string)
Dynamically allocate the string with malloc, populate string, and return the returned address by malloc. This returned address is allocated from the heap and will be allocated until you do not manually free it (or the program does not terminate).
char *getRandomString(void)
{
char *word;
word = malloc (sizeof (random_length));
// ...instructions that will fill word with random characters.
return word;
}
After you have done with the allocated string, remember to free the string.
Or another thing can be done, if you cannot use malloc which is define the local string in the getRandomString as static which makes the statically declared array's lifetime as long as the program runs.
char *getRandomString(void)
{
static char word[LENGTH];
// ...instructions that will fill word with random characters.
return word;
}
Or simply make the char word[128]; global.
As I understand, malloc is not an option.
Write a couple of functions to a) get a random integer (strings length), and b)a random char.
Then use those to build your random string.
For example:
//pseudocode
static char random_string[MAX_STRING_LEN];
char *getRandomString()
{
unsigned int r = random_number();
for (i=0;i<r;i++){
random_string[i] = random_char();
}
random_string[r-1] = '\0';
}
If you are not allowed to use malloc you'll have to declare an array that can be the maximum possible size at file scope and fill it with random characters.
#define MAX_RANDOM_STRING_LENGTH 1024
char RandomStringArray[MAX_RANDOM_STRING_LENGTH];
char *getRandomString(size_t length)
{
if( length > ( MAX_RANDOM_STRING_LENGTH - 1 ) ) {
return NULL; //or handle this condition some other way
} else {
// fill 'length' bytes in RandomStringArray with random characters.
RandomStringArray[length] = '\0';
return &RandomStringArray[0];
}
}
int main()
{
char *string = getRandomString(100);
printf("Random string is: %s\n", string);
return 0;
}
Both of your examples are returning pointers to local variables - that's generally a no-no. You won't be able to create memory for your caller to use without malloc(), which isn't defined in stdio.h, so I guess your only option is to make word static or global, unless you can declare it in main() and pass the pointer to your random string function to be filled in. How are you generating random numbers with only the functions in stdio.h?

Resources