C的printf不打印字符串(char数组)

时间:2011-07-18 17:48:18

标签: c string printf

我的问题基本上是使用printf打印一个char数组。

在某些情况下,它会打印出结果:

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

有时不会:

int main(int argc, char** argv) {
  char* orig = "@reveals#?the treasure chest#$President Barack H. Obama#";
  printf("%s\n", reArrange(orig));

  return (EXIT_SUCCESS);
}

这是完整的代码(包括主要功能):

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

6 个答案:

答案 0 :(得分:5)

您正在返回指向驻留在堆栈中的内存的指针。封闭函数(rearranged)返回后,reArrange不可用,并且可能包含垃圾。

您可能需要malloc rearranged或全局声明。

答案 1 :(得分:3)

make char *不是仅返回reArrange(),而是接受可以写入结果的缓冲区。现在调用者必须为您的函数提供合适的缓冲区,并且您不再需要内存管理。你只是strncpy()安排到缓冲区。为了确保缓冲区足够大,用户还应该在第三个参数中提供缓冲区的大小:

char *rArrange(char *orig, char *result, int resultSize)
{
    if (!result || resultSize == 0)
        return NULL;

    /* your code here */

    strncpy(result, arranged, resultSize);
    return result;
}

存储结果的替代malloc()不是非常用户友好的(用户必须freemem()缓冲区但可能不知道这一点)。使用静态/全局缓冲区不是非常线程安全的。

答案 2 :(得分:1)

问题是你的函数reArrange返回一个指向它不再控制的内存的指针。返回rearranged数组的地址。返回发生后,此数组实际上不再存在 - 内存可以并且将被重用。

修复错误的快速黑客攻击是将rearranged声明为static。长期解决方法是使用malloc()或等效的方法了解C的工作原理和代码。

答案 3 :(得分:1)

使用char rearranged[origSize];创建了一个新的字符数组,该数组在reArrange终止后超出范围。因此,在reArrange的生命周期中,rearranged是一个指向有意义的东西的指针;因此,orig = rearranged是有道理的。

但是一旦它超出范围,reArrange(orig)会返回指向rearranged的指针,这是一个悬空指针,现在rearranged不再存在。

答案 4 :(得分:1)

您的功能需要两个参数:

char* reArrange(char* orig)

应该是:

char* reArrange(char *rearragned, char* orig) {

// make your magic here!

}

呼叫序列:

char input[SIZE];
char rearrange [SIZE];

// initialize everything! Don't forget to rearrange[0] ='\0\;!!!

rearrange(rearranged, input);

// do you printing....

您还应该学习如何正确使用指针并查找“切换”。

答案 5 :(得分:0)

您确定代码的以下部分有效吗?

char* reArrange(char* orig) {
  int origSize = strlen(orig);

  char subject[origSize], action[origSize], object[origSize];

我的意思是origSize必须是const,它不能是动态值。您应该使用mallocsubject , action and object分配快照。 此外,您可以考虑一些指导原则:

1而不是:

for(i = 0; i < origSize; i++) {
    char ch = orig[i];    
    if(ch == SUBJECT) {
      state = SUBJECT;
}

你可以:

char ch;//declare char ch outside for loop
for(i = 0; i < origSize; i++) {
    ch = orig[i];

    if(ch == SUBJECT) {
      state = SUBJECT;
    }

2您可能希望使用switch语句而不是if语句,这会使您的代码看起来很棒。