C's printf doesn't print a string (char array) out
My question is basically using printf print a char array.
In some cases, it prints the result out:
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
printf("The input: %s\n", orig);
printf("The output: %s\n", reArrange(orig));
return (EXIT_SUCCESS);
}
sometimes not:
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
printf("%s\n", reArrange(orig));
return (EXIT_SUCCESS);
}
Here is the complete code (the main function is included):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUBJECT '$'
#define ACTION '@'
#define OBJECT '?'
#define END '#'
char* reArrange(char* orig) {
int origSize = strlen(orig);
char subject[origSize], action[origSize], object[origSize];
//int i;
//for(i = 0; i < origSize; i++) {
// subject[i] = ' ';
// action[i] = ' ';
// object[i] = ' ';
//}
int subjectIndex = 0, actionIndex = 0, objectIndex = 0;
int timesEndCharShowUp = 0;
char state;
int i;
for(i = 0; i < origSize; i++) {
char ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
else if(ch == ACTION) {
state = ACTION;
}
else if(ch == OBJECT) {
state = OBJECT;
}
else if(ch == END) {
if(timesEndCharShowUp == 3) {
break;
}
else {
timesEndCharShowUp++;
}
}
else {
if(state == SUBJECT) {
开发者_如何转开发subject[subjectIndex++] = ch;
}
else if(state == ACTION) {
action[actionIndex++] = ch;
}
else if(state == OBJECT) {
object[objectIndex++] = ch;
}
}
}
subject[subjectIndex] = '\0';
action[actionIndex] = '\0';
object[objectIndex] = '\0';
char rearranged[origSize];
sprintf(rearranged, "%s %s %s.\0", subject, action, object);
//printf("%s\n", rearranged);
orig = rearranged;
return orig;
}
int main(int argc, char** argv) {
char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
// printf("The input: %s\n", orig);
// printf("The output: %s\n", reArrange(orig));
printf("result: ");
printf("%s\n", reArrange(orig) );
//fflush(stdout);
return (EXIT_SUCCESS);
}
You are returning a pointer to memory that resides on the stack. rearranged
is not available after the enclosing function (reArrange
) returns and may contain garbage.
You may want to malloc
rearranged
or declare it globally.
Instead of only returning a char *
, make reArrange()
accept a buffer to which it can write the result. Now the caller must provide a suitable buffer to your function, and you have no problems with memory management anymore. You merely strncpy() arranged to the buffer. To be sure the buffer is large enough, the user should also provide the size of the buffer, in a 3rd argument:
char *rArrange(char *orig, char *result, int resultSize)
{
if (!result || resultSize == 0)
return NULL;
/* your code here */
strncpy(result, arranged, resultSize);
return result;
}
The alternative malloc()
to store the result is not very user fiendly (the user must freemem() the buffer but may not be aware of this). Using a static/global buffer is not very thread-safe.
Your function needs two parameters:
char* reArrange(char* orig)
Should be:
char* reArrange(char *rearragned, char* orig) {
// make your magic here!
}
Calling sequence:
char input[SIZE];
char rearrange [SIZE];
// initialize everything! Don't forget to rearrange[0] ='\0\;!!!
rearrange(rearranged, input);
// do you printing....
You should also learn how to use pointers correctly and look up "switch".
The problem is that your function reArrange
returns a pointer to memory that it no longer controls. The address of the rearranged
array is returned. After the return occurs, this array effectively no longer exists -- the memory can, and will, be reused.
A quick hack which fixes your mistake is to declare rearranged
as static
. The long term fix is to learn how C works and code something using malloc()
or an equivalent.
With char rearranged[origSize];
you created a new character array which goes out of scope once reArrange
terminates. So during the lifetime of reArrange
, rearranged
is a pointer which points to something meaningful ; hence, orig = rearranged
makes sense.
But once it goes out of scope, reArrange(orig)
returns the pointer to rearranged
which is a dangling pointer now rearranged
does not exist anymore.
Are you sure that the following section of the code works?
char* reArrange(char* orig) {
int origSize = strlen(orig);
char subject[origSize], action[origSize], object[origSize];
i mean origSize
has to be a const
it can't be a dynamic value. You should use malloc
for allocating apace for subject , action and object
.
Moreover, you might consider a few guidelines:
1 Instead of:
for(i = 0; i < origSize; i++) {
char ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
You can have:
char ch;//declare char ch outside for loop
for(i = 0; i < origSize; i++) {
ch = orig[i];
if(ch == SUBJECT) {
state = SUBJECT;
}
2 you may like to use a switch
statement instead of if
, that will make your code look great.
精彩评论