Как я могу вернуться к строковому адресу и затем назначить его новой строке? - PullRequest
0 голосов
/ 12 апреля 2010

У меня есть 1 функция, для которой я хочу вернуть адрес назначенной строки основной функции и назначить новый указатель строки с тем же адресом, чтобы новая строка содержала содержимое старой строки.

Например:

 unknown_datatype function()
 {
      char *old = "THE STRING";
      return old;
 }

 int main()
 {
      char *snew = "";
      snew = function();
      return 0;
 }

* unknown_datatype означает, что я не знаю, что туда поместить ...

* Как я могу подойти к этому, не меняя ничего в методе main ()

Ответы [ 7 ]

3 голосов
/ 12 апреля 2010

Как правило, вы передаете адрес первого элемента в массиве символов, а также длину, и функция заполняет его.

int fillMyString(char *str, int buffer_size)
{
  if(buffer_size > strlen("test"))
  {
    strncpy(str, "test", buffer_size-1);
    str[buffer_size-1] = '\0';
    return strlen(str);
  }

  return 0;
}


//In some function or main
char buffer[1024];
fillMyString(buffer, 1024);
ASSERT(!strcmp(buffer, "test"));

Редактировать: Вы упомянули, что по какой-то причине вам необходимо вернуть символ *. В этом случае я бы предложил использовать malloc для выделения строки внутри функции, но обязательно при каждом вызове функции вы free возвращаете значение в конце концов.

1 голос
/ 12 апреля 2010

Вы можете просто вернуть char*. Поскольку вы возвращаете указатель на строковый литерал, вероятно, лучше всего вернуть const char*, поскольку вы не можете изменить строковый литерал:

const char* function()

И также вы хотите присвоить возвращаемое значение для const char*:

const char* snew = 0;
snew = function();
0 голосов
/ 13 апреля 2010

Ваш вопрос и пример противоречат друг другу.

Это то, что вы ищете? ниже приведены два простых решения.

char * func (char *);

int main ()

{

char *newstring="Hey";

newstring = func(newstring);

printf("New string : %s\n", newstring);

}

char * func (char * s)

{

printf("Old string : %s\n", s);

s="Hello";

return(s);

}

или же решение, заданное Y_Y, тоже подойдет, если ваша строка создана в вызове функции. На случай, если вы не хотите использовать malloc, нижеприведенное решение работает.

char * func ();

int main ()

{

char *newstring="";

newstring = func();

printf("New string : %s\n", newstring);

}

char * func ()

{

char *s="Hello";

printf("Old string : %s\n", s);

return(s);

}

0 голосов
/ 12 апреля 2010
char * function()
{
    char *old = "THE STRING";
    return old;
}

int main()
{
     char *snew = "";
     snew = function();
     return 0;
}
0 голосов
/ 12 апреля 2010

ОК, вот ответ: Так как я не могу РЕДАКТИРОВАТЬ основной (ЗНАЧЕНИЕ Я НЕ МОГУ ПРОЙТИ ЛЮБОЙ ПАРАМЕТР), возможно следующее решение:

char *function()
{

    char *old;
    old = (char*)malloc(9999);
    strcpy(old,"THE STRING");
    return old;
}

int main()
{
    char *snew = "";
    snew = function();
    return 0;
}

Спасибо всем, кто ответил.

0 голосов
/ 12 апреля 2010

Как отметил Брайан, самая идиоматическая вещь, которую нужно сделать в C, это передать буфер, поэтому вы должны сделать:

int give_me_a_string(char* buffer, int buffersize)
{
   const char* result = "Hello world!";
   int requiredbufferlen = strlen(result)+1;
   if ( (buffer==0) || (buffersize<requiredbufferlen) ){
       errno = EINVAL;
       return -1;
   }
   strncpy(buffer,"Hello world!",buffersize);
   buffer[buffersize-1]='\0';
   return 0;
}

int main(int argc, char* argv[])
{
    int buffersize = 256;
    char* buffer = (char*) malloc(buffersize);
    if ( buffer == 0 ){
       printf("Out of memory!\n");
       return 1;
    }
    if ( give_me_a_string(buffer,buffersize) < 0 ){
       printf("Oh my god, there's an error!\n");
       free(buffer);
       return 1;
    }else{
       printf("%s\n",buffer);
    }
    free(buffer);
    return 0;
}

Теперь, если вам абсолютно не нужно передавать в буфер, тогдаВы можете написать:

char* give_me_a_string(void)
{
   const char* str="Hello world!";
   int buffersize = strlen(str)+1;
   char* result=(char*) malloc(buffersize);
   if ( result == 0 ){
       return 0;
   }
   strncpy(result,str,buffersize);
   result[buffersize-1]='\0';
   return result;
}

Однако, если вы используете вышеизложенное, вы должны запомнить free() результат.Тем не менее, я настоятельно рекомендую вам использовать первый подход;когда функция возвращает объект указателя, неясно, кто является владельцем (то есть кто отвечает за освобождение строки).Требуя, чтобы вызывающая сторона передала в буфер, вы делаете это владение явным (то есть вызывающая сторона владеет буфером и должна сама освободить его).

Существует одно последнее решение, которое вы можете использовать.Если вы возвращаете постоянную строку, то это приемлемо;однако, если вам нужно вычислить строку, это сделает ее не входящей, и поэтому я настоятельно рекомендую не делать это.На самом деле, я бы настоятельно рекомендовал против этого решения, даже если вы возвращали постоянную строку, потому что тогда API не может адаптироваться к случаю, когда вам нужно вычислить строку.Этот метод заключается в использовании общей глобальной переменной, которая содержит результат, поэтому он будет выглядеть следующим образом:

// declaration
char* give_me_a_string(void);

// implementation
char* global_string = "Hello world!";
char* give_me_a_string(void)
{
   return global_string;
}

Это последнее решение не требует освобождения, поскольку сама функция является владельцем.Если бы вы делали это с вычисляемой строкой, она бы выглядела следующим образом:

// declaration
char* give_me_a_string(void);

// implementation
char* global_string = 0;
static void deallocate_global_string()
{
    free(global_string);
    global_string=0;
}

char* give_me_a_string(void)
{
   if ( global_string == 0){
       // allocate global_string
       // ...
       // initialize global_string
       // ...
       // ensure it is eventually freed
       atexit(&deallocate_global_string);
   }
   return global_string;
}

Как должно быть очевидно, если вы сделаете это, это не реентерабельный (он не будет работать с несколькими потоками), итак что это действительно, действительно ужасная идея.Если вы обожглись, позвольте мне сказать, что я вас предупреждал.

0 голосов
/ 12 апреля 2010

Неизвестный тип данных должен был бы быть char*, но в этом случае он не будет делать то, что вы ожидаете, поскольку переменные в function() являются локальными переменными, которые исчезнут после выхода из функции и будут вытолкнуты из стека. Вы можете использовать malloc() вызов внутри функции и вернуть указатель на новую строку. Только не забудьте освободить его, когда закончите.

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