开发者

C's printf doesn't print a string (char array) out

开发者 https://www.devze.com 2023-03-21 17:16 出处:网络
My question is basically using printf print a char array. In some cases, it prints the result out: int main(int argc, char** argv) {

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号