Чтение нескольких строк до EOF - PullRequest
0 голосов
/ 21 февраля 2019
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

//the function
char* scan(char *string)
{
  int c; //as getchar() returns `int`
  string = malloc(sizeof(char)); //allocating memory

  string[0]='\0';

  for(int i=0; i<100 && (c=getchar())!='\n' && c != EOF ; i++)
  {
    string = realloc(string, (i+2)*sizeof(char)); //reallocating memory
    string[i] = (char) c; //type casting `int` to `char`
    string[i+1] = '\0'; //inserting null character at the end
  }

  return string;
}
char** bigScan(char **string)
{

  int c;
  string=malloc(sizeof(char *));
  string[0]='\0';
  for(int i=0;(c=getchar()!=EOF);i++)
  {
    *string = realloc(string, (i+2)*sizeof(char *)); //reallocating memory
    string[i] = scan(string[i]); //type casting `int` to `char`
    string[i+1] = '\0'; //inserting null character at the end

  }
  return string;

}
int main(void)
{
  char **buf; //pointer to hold base address of string
  buf=bigScan(buf);
  printf("%s\n",buf[0] );


}

Таким образом, в основном функция сканирования читает каждую строку до EOF или до новой строки. Задача bigScan - читать несколько строк (указатель на строки), вызывая функцию сканирования до тех пор, пока мы не нажмем EOF.По сути, большое сканирование возвращает указатель на указатели, и мы можем прочитать весь текст, используя это.Что я делаю неправильно в моем подходе?В основном вызывая функцию сканирования в моем bigScan, пока я не нажму EOF.

  Ideal Input:
  "Hi guys and girls
  This is a message in multiple lines."
  Ideal Output:
  "Hi guys and girls
  This is a message in multiple lines."

1 Ответ

0 голосов
/ 21 февраля 2019
  1. (c=getchar()!=EOF) внутри bigScan недействительно.Он присваивает значение 1 или 0 для c, поскольку значение bool является результатом сравнения !=.
  2. getchar() внутри bigScan приведет к потере одного символав строке, так как этот символ нигде не сохраняется.
  3. Недопустимое распределение в bigScan.Вы не должны выделять память для строки *string = realloc(string, но вы должны выделять память для самих указателей, т.е.string = realloc(string, ... sizeof(char*)).
  4. NULL - конечное значение, используемое для указателей.Не используйте '\0' для указателей.
  5. Используйте size_t для хранения размеров.
  6. Нет смысла передавать значения параметров, если вы их перезаписываете.В этой функции переменная a не используется void f(int a) { a = 1; }, так как переменная string в обеих ваших функциях назначается сразу после ввода функции.
  7. Функция scan имеет жесткий предел i<100символы.

Ниже приведена несколько исправленная версия ваших функций.Также с переименованными переменными.И убрали параметры.И разные отступы.И с assert ионами из стандарта #include <assert.h> для использования в качестве примитивной проверки ошибок.И с ungetc символ, прочитанный в bigScan, не исчезает.И я не запускал этот код, поэтому он содержит массу ошибок.

char* scan(void)
{
  char *string = malloc(sizeof(*string));
  assert(string != NULL);
  string[0] = '\0';
  size_t stringlen = 1;

  for(int c; (c=getchar()) != '\n' && c != EOF;) {
    void * const ptr = realloc(string, (stringlen + 1) * sizeof(*string));
    assert(ptr != NULL);
    stringlen++;
    string[stringlen - 2] = c;
    string[stringlen - 1] = '\0'; //inserting null character at the end
  }

  return string;
}


char** bigScan(void)
{
  char **strings = malloc(sizeof(*strings));
  assert(strings != NULL);
  strings[0] = NULL;
  size_t stringslen = 1;

  for(int c; (c = getchar()) != EOF;) {
    ungetc(c);

    void * const ptr = realloc(strings, (stringslen + 1) * sizeof(*strings)); 
    assert(ptr != NULL);
    strings = ptr;
    stringslen++;
    strings[stringslen - 2] = scan();
    strings[stringslen - 1] = NULL;

  }

  return strings;
}
...