C printf не печатает строку (массив символов) - PullRequest
2 голосов
/ 18 июля 2011

Мой вопрос в основном заключается в использовании 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 ]

5 голосов
/ 18 июля 2011

Вы возвращаете указатель на память, которая находится в стеке.rearranged недоступно после возврата включающей функции (reArrange) и может содержать мусор.

Возможно, вы захотите malloc rearranged или объявите его глобально.

3 голосов
/ 18 июля 2011

Вместо того, чтобы только возвращать char *, заставить reArrange() принять буфер, в который он может записать результат.Теперь вызывающая сторона должна предоставить подходящий буфер для вашей функции, и у вас больше не будет проблем с управлением памятью.Вы просто strncpy () расположены в буфере.Чтобы убедиться, что буфер достаточно большой, пользователь должен также указать размер буфера в 3-м аргументе:

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 () буфер, но может не знать об этом).Использование статического / глобального буфера не очень потокобезопасно.

1 голос
/ 18 июля 2011

Ваша функция нуждается в двух параметрах:

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....

Вы также должны научиться правильно использовать указатели и искать «переключатель».

1 голос
/ 18 июля 2011

С помощью char rearranged[origSize]; вы создали новый массив символов, который выходит из области видимости после завершения reArrange.Таким образом, в течение жизни reArrange, rearranged является указателем, который указывает на что-то значимое;следовательно, orig = rearranged имеет смысл.

Но как только он выходит из области видимости, reArrange(orig) возвращает указатель на rearranged, который теперь является висящим указателем rearranged больше не существует.

1 голос
/ 18 июля 2011

Проблема в том, что ваша функция reArrange возвращает указатель на память, которой она больше не управляет.Адрес массива rearranged возвращается.После того, как происходит возврат, этот массив больше не существует - память может и будет использоваться повторно.

Быстрый взлом, который исправляет вашу ошибку, состоит в объявлении rearranged как static.Долгосрочное исправление состоит в том, чтобы узнать, как работает C, и кодировать что-либо, используя malloc() или эквивалентный код.

0 голосов
/ 19 июля 2011

Вы уверены, что следующий раздел кода работает?

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

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

Я имею в виду origSize должно быть const, оно не может быть динамическим значением.Вы должны использовать malloc для выделения apace для subject , 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, который сделает ваш код великолепным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...