сохранить char * из возвращаемого значения функции - PullRequest
2 голосов
/ 22 декабря 2010

Я пытаюсь реализовать функцию, которая читает из последовательного порта (Linux) и возвращает char *. Функция работает нормально, но как бы я сохранил возвращаемое значение из функции. пример функции

char  *ReadToSerialPort()
{
 char *bufptr;
 char buffer[256];  // Input buffer/ /
 //char *bufptr;      // Current char in buffer //
 int  nbytes;       // Number of bytes read //

 bufptr = buffer;

 while ((nbytes = read(fd, bufptr, buffer+sizeof(buffer)-bufptr -1 )) > 0)
 {
  bufptr += nbytes;
  //  if (bufptr[-1] == '\n' || bufptr[-1] == '\r')
  /*if ( bufptr[sizeof(buffer) -1] == '*' && bufptr[0] == '$' )
  {
   break;
  }*/

 } // while ends


 if ( nbytes ) return bufptr;
 else return 0;


 *bufptr = '\0';

} // end ReadAdrPort


//In main
int main( int argc , char *argv[])
{ 
  char *letter;
  if(strcpy(letter,  ReadToSerialPort()) >0 )
  {
   printf("Response is %s\n",letter);
  }
}

Ответы [ 4 ]

5 голосов
/ 22 декабря 2010

Вы должны выделить буфер в куче с malloc и вернуть его. Пользователи вашей функции будут нести ответственность за освобождение памяти (и ваша документация должна четко указывать это!)

Простое изменение будет

char* buffer = (char*)malloc(256);
// beware that now `sizeof(buffer)` will be not 256 any more, but 4, so
// you have to define your constant for it.
...
if (nbytes) return buffer;
free(buffer);
return 0;

...
int main(int argc, char *argv[])
{ 
    char *letter = ReadToSerialPort();
    if (letter)
    {
        printf("Response is %s\n", letter);
        free(letter);
        return 0;
    }
    return 1;
}

Обратите внимание, что код *bufptr = '\0'; должен быть до return, а не после!

EDIT
Ваш код выглядит так:

char *ReadToSerialPort()
{
    const int buffer_size = 256;
    char *buffer = (char *)malloc(buffer_size);
    char *bufptr = buffer;
    int  nbytes;

    while ((nbytes = read(fd, bufptr, buffer+buffer_size-bufptr-1)) > 0)
    {
        bufptr += nbytes;
    }

    *bufptr = '\0';

    if (bufptr != buffer)
        return bufptr;
    // else cleaning up
    free(buffer);
    return 0;
}

Мне любопытно, откуда взялась fd

0 голосов
/ 22 декабря 2010

Вы должны изменить подпись ReadToSerialPort () , чтобы также сообщить вызывающей стороне, сколько байтов вы возвращаете. Так что вы можете сделать это:

int ReadToSerialPort(char** data);

или это:

void ReadToSerialPort(char** data, int* num_of_bytes);

и вы несете ответственность за выделение памяти внутри ReadToSerialPort ().

Пользователь будет делать что-то вроде (не проверено):

int main( int argc , char *argv[])
{ 
  char* data = NULL;
  int count = 0;
  ReadToSerialPort(data, &count);
  if (data != NULL && count > 0) // Let's suppose count returns as 5
  {
    printf("data[0]:%x data[1]:%x data[2]:%x data[3]:%x data[4]:%x\n", data[0], data[1], data[2], data[3], data[4]);
  }

  // and the user is responsible for deallocating data himself
  free(data);

  return 0;
}
0 голосов
/ 22 декабря 2010

Вы должны указать свою функцию немного больше.Вы не можете просто сказать, что это «возвращает char *».На какие символы он указывает?В статическом буфере?На куче (выделено new)?Похоже, вы пытаетесь вернуть указатель на локальный буфер (размещенный в стеке), что является ошибкой.Или верните std::string.

0 голосов
/ 22 декабря 2010

Исправьте ваш основной код так, чтобы он выглядел следующим образом:

//In main
int main( int argc , char *argv[])
{ 
  char *letter = ReadToSerialPort();
  if(letter != NULL)
  {
   printf("Response is %s\n",letter);
  }
}

Убедитесь, что вы используете буфер, объявленный как static в ReadToSerialPort() ..... т.е.:

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