Асинхронный HTTP-клиент Boost Beast + std :: future

Ниже приведен быстрый подход к удалению потенциала '\n' из строки, сохраненной в fgets(). Он использует strlen() с двумя тестами.

char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {

  size_t len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n') {
    buffer[--len] = '\0';
  }

Теперь используйте buffer и len по мере необходимости.

Этот метод имеет побочное преимущество len значение для последующего кода. Это может быть быстрее, чем strchr(Name, '\n'). Ref YMMV, но оба метода работают.


buffer, из оригинала fgets() не будет содержать в "\n" при некоторых обстоятельствах: A) Линия был слишком длинным для buffer, поэтому только char, предшествующий '\n', сохраняется в buffer. В потоке остаются непрочитанные символы. B) Последняя строка в файле не заканчивалась символом '\n'.

Если на входе есть встроенные нулевые символы '\0' в нем где-то, длина, сообщенная strlen(), не будет содержать местоположение '\n'.


Некоторые другие ответы ' Проблемы:

  1. strtok(buffer, "\n"); не удаляет '\n', когда buffer - "\n". Из этого ответа - изменен после этого ответа, чтобы предупредить об этом ограничении.
  2. Следующие ошибки приводятся в редких случаях, когда первый char, прочитанный fgets(), является '\0'. Это происходит, когда ввод начинается со встроенного '\0'. Тогда buffer[len -1] становится buffer[SIZE_MAX] доступным к памяти, конечно, вне допустимого диапазона buffer. Что-то хакер может попытаться найти в глупости чтения текстовых файлов UTF16. Это было состояние ответа , когда этот ответ был написан. Позже не-OP отредактировал его, чтобы включить код, подобный проверке этого ответа на "".
    size_t len = strlen(buffer);
    if (buffer[len - 1] == '\n') {  // FAILS when len == 0
      buffer[len -1] = '\0';
    }
    
  3. sprintf(buffer,"%s",buffer); - неопределенное поведение: Ref . Кроме того, он не сохраняет никаких ведущих, разделяющих или завершающих пробелов. Теперь удален .
  4. [Редактировать из-за хорошего ответа ] Нет проблем с 1 лайнером buffer[strcspn(buffer, "\n")] = 0;, отличным от производительности, по сравнению с strlen(). Производительность при обрезке обычно не является проблемой, поскольку код вводит I / O - черную дыру процессорного времени. Если следующий код нуждается в длине строки или имеет высокую производительность, используйте этот подход strlen(). Иначе strcspn() является прекрасной альтернативой.

3
задан Xeverous 4 March 2019 в 19:52
поделиться