2014-11-24 4 views
4

Я написал эту небольшую функцию, чтобы прочитать все данные от stdin.Читать все данные stdin C

мне нужно знать, если эта функция POSIX совместимой (этим, я имею в виду, что будет работать под Unix и Unix-подобных системах) по крайней мере, он работает на Windows ...

char* getLine() 
{ 
    int i = 0, c; 
    char* ptrBuff = NULL; 

    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     if ((ptrBuff = (char*)realloc(ptrBuff, sizeof (char)+i)) != NULL) 
      ptrBuff[i++] = c; 
     else 
     { 
      free(ptrBuff); 
      return NULL; 
     } 
    } 

    if (ptrBuff != NULL) 
     ptrBuff[i] = '\0'; 

    return ptrBuff; 
} 

Функция читает все данные из stdin до получения '\n' или EOF и возвращает указатель на новое местоположение со всеми символами. Я не знаю, является ли это наиболее оптимальным или безопасным способом сделать это, и не знаю, работает ли это в Unix и Unix-подобных системах ... поэтому мне нужна небольшая помощь здесь. Как я могу улучшить эту функцию? или есть лучший способ получить все данные от stdin, не оставляя мусор в буфере? Я знаю, что fgets() вариант, но он может оставить мусор, если пользовательский ввод больше, чем ожидалось ... плюс, я хочу получить все символы, которые пользователь написал.

EDIT:

Новая версия getLine():

char* readLine() 
{ 
    int i = 0, c; 
    size_t p4kB = 4096; 
    void *nPtr = NULL; 
    char *ptrBuff = (char*)malloc(p4kB); 

    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     if (i == p4kB) 
     { 
      p4kB += 4096; 
      if ((nPtr = realloc(ptrBuff, p4kB)) != NULL) 
       ptrBuff = (char*)nPtr; 
      else 
      { 
       free(ptrBuff); 
       return NULL; 
      } 
     } 
     ptrBuff[i++] = c; 
    } 

    if (ptrBuff != NULL) 
    { 
     ptrBuff[i] = '\0'; 
     ptrBuff = realloc(ptrBuff, strlen(ptrBuff) + 1); 
    } 

    return ptrBuff; 
} 

Последнее редактирование:

Это последняя версия функции char* readLine(). Теперь я не вижу больше ошибок и лучших способов улучшить его, если кто-то знает лучший способ, просто скажите мне, пожалуйста.

char* readLine() 
{ 
    int c; 
    size_t p4kB = 4096, i = 0; 
    void *newPtr = NULL; 
    char *ptrString = malloc(p4kB * sizeof (char)); 

    while (ptrString != NULL && (c = getchar()) != '\n' && c != EOF) 
    { 
     if (i == p4kB * sizeof (char)) 
     { 
      p4kB += 4096; 
      if ((newPtr = realloc(ptrString, p4kB * sizeof (char))) != NULL) 
       ptrString = (char*) newPtr; 
      else 
      { 
       free(ptrString); 
       return NULL; 
      } 
     } 
     ptrString[i++] = c; 
    } 

    if (ptrString != NULL) 
    { 
     ptrString[i] = '\0'; 
     ptrString = realloc(ptrString, strlen(ptrString) + 1); 
    } 
    else return NULL; 

    return ptrString; 
} 
+1

См. Это сообщение в блоге: http://powerfield-software.com/?p=65 - он также использовался как ответ на пару вопросов здесь, на SO. – paxdiablo

+0

Да, ваша функция POSIX, я тестировал ее с помощью gcc в Linux и, похоже, работает так, как ожидалось. –

+1

Выделение одного байта в такое время может привести к квадратичной производительности - что не очень хорошо. Вы должны выделять блоки данных одновременно, возможно удваивая пространство, выделяемое каждый раз, когда вам нужно больше места. Следует также отметить, что 'ptrBuff = realloc (ptrBuff, new_size);' утечка памяти при сбое распределения, потому что вы пишете NULL по единственному указателю на предыдущее распределение памяти. 'Free (ptrBuff);' является безопасным, потому что 'free (NULL)' является no-op. Он не освобождает память, потому что 'ptfBuff' больше не указывает на нее. Используйте 'void * new_space = realloc (ptrBuff, new_size);' и проверьте значение nullness. –

ответ

1

POSIX-совместимый: есть!

Вы звоните только getchar(), malloc(), realloc() и free(), все из которых являются стандартные функции C и, следовательно, также доступно в соответствии с POSIX. Насколько я могу судить, вы также выполнили все необходимые проверки кода возврата. Учитывая, что код будет хорош в любой среде, поддерживающей malloc() и stdin.

Смежные вопросы