C чтение строк из стандартного ввода - PullRequest
1 голос
/ 13 июля 2020

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
  int Chars;
  int size = 10;
  char *string;

  printf("Please enter a string: ");
  string = (char*) malloc(size);
  Chars = getline(&string, &size, stdin);

  if (Chars == -1)
  {
    puts("ERROR!");
  }
  else
  {
    puts("You entered the following string: ");
    puts(string);
    printf("\nCurrent size for string block: %d", Chars);
  }
  return 0;
}

Я всегда получаю код ошибки : [Ошибка] Id повторно выполнил 1 статус выхода

1 Ответ

0 голосов
/ 13 июля 2020

Я воспроизвел ошибку связывания на DevC ++ , в котором getline() кажется отсутствующим даже после принудительного применения последних C ревизий с помощью g cc параметров компилятора, таких как как -std=c11.

Итак, я переписал ваш код, используя fgets():

char *fgets(char *s, int size, FILE *stream);

Он наверняка более переносимый, чем getline, но имеет несколько отличий:

  • Он читает до size-1 символов, если новая строка не встречается до этого предела (он автоматически добавляет терминатор строки). Таким образом, он не управляет перераспределением буфера
  • Результирующая строка содержит символ '\n', если он найден
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_STR_SIZE 32

int main( void )
{
  int len = 0;
  char *str;

  printf("Please enter a string: ");
  str = malloc(MAX_STR_SIZE);     /* (1) */

  while( 1 )
  {
    size_t newline_pos;
    
    fgets( str, MAX_STR_SIZE, stdin );
    /* (2) */

    if( len == 0) /* (3) */
    {
      puts("You entered the following string: ");
    }

    newline_pos = strcspn(str, "\n" );

    str[newline_pos] = '\0';
    len += strlen(str);   /* (4) */  
    fputs(str, stdout);

    if(newline_pos < MAX_STR_SIZE-1) /* (5) */
      break;
  }

  printf("\n\nCurrent size for string block: %d", len);

  free( str ); /* (6) */
  return 0;
}

Итак, в основном, я просто использую fgets для чтения от stdin, итерация до тех пор, пока не будет найден символ '\n'. Чтобы понять, выполняется ли это условие, я использую функцию strcspn () , и я использую ту же функцию для удаления новой строки из полученной строки.

Несколько примечаний / предположений ( проверьте соответствующий номер в разделе кода):

  1. Приведение результата malloc требуется только в том случае, если вы компилируете с помощью компилятора C ++. Его можно опустить в C
  2. Удалено fgets проверка ошибок: возвращает NULL в случае ошибки (символы не читаются до того, как будет найден EOF. Это не произойдет при чтении из stdin)
  3. Проверяя len==0, мы убеждаемся, что "You entered the following string: " печатается только один раз
  4. Длина строки вычисляется путем суммирования длины строк, прочитанных на каждой итерации
  5. Условие break выполняется, если строка содержит '\n'. В противном случае возвращаемое значение strcspn будет MAX_STR_SIZE
  6. Даже если ОС освободит всю динамическую c память, используемую программой, при возврате это всегда хорошая привычка free ing это все равно
...