Нужно уметь разбирать слова по пробелам в ц.Также нужно знать, правильно ли я распределяю память? - PullRequest
1 голос
/ 07 марта 2019

Я пишу программу на c, которая читает текст из текстового файла, затем случайным образом выбирает слова из файла и, если слова больше или равны шести, добавляет слова вместе, удаляет пробелы и, наконец, печатает новое слово. (Я использую перенаправление на linux "<" для чтения в файле) </p>

Example input: "cheese and crackers"

New word should be: cheesecrackers

Вот код:

int main (void)
{
    int ch;
    char *ptrChFromFile;
    int strSize = 1;
    int i;
    int numberOfWords = 1;

    ptrChFromFile = malloc (sizeof (char));

    if (ptrChFromFile == NULL) {
        puts ("COULDN'T ALLOICATE MEMORY");
        exit (EXIT_FAILURE);
    }

    while ((ch = getchar ()) != EOF) {
        ptrChFromFile =
            realloc (ptrChFromFile, (strSize + 1) * sizeof (char));

        if (ptrChFromFile == NULL) {
            puts ("failed to allocate memory");
            exit (EXIT_FAILURE);
        }

        if (ch == ' ') {
            numberOfWords++;
        }

        ptrChFromFile[strSize] = ch;
        strSize++;
    }

    ptrChFromFile[strSize] = 0;

    char **ptrWords = malloc (sizeof (char *) * strSize);


    for (i = 0; i < strSize; i++) {
        if (ptrChFromFile[i] != ' ') {
            ptrWords[i] = &ptrChFromFile[i];
        }
        else {
            ptrWords[i] = 0;
        }
    }

    free (ptrChFromFile);
    free (ptrWords);
    return 0;
}

То, с чем я борюсь, это:

1) Я выделяю правильный размер памяти для указателей?

2) Как я могу разобрать каждое слово по пробелу, не используя никаких специальных методов из библиотеки string.h (например, strtok). Тогда как мне сохранить эти слова в указателе * ptrWords?

так что ptrWords должен выглядеть так:


сыр | и | крекеры

 0        1      2

Затем я хочу пройтись по ptrWords и проверить, больше ли длина каждого слова в указателе или равна шести. Если они хранятся в указателе ptrOutputWord.

, тогда ptrOutputWord должен выглядеть так:


сыр | крекеры

 0        1      

Наконец, я хочу напечатать значения в ptrOutputWord как одно слово без пробелов.

Я пытался объяснить, что именно хочу делать. Спасибо всем, кто может помочь заранее.

РЕДАКТИРОВАТЬ: я изменил код, чтобы он отражал только часть, которая должна читаться в символах, и перераспределяю размер указателя на единицу каждый раз, когда читается новый символ, но правильный объем памяти не выделяется ,

1 Ответ

1 голос
/ 08 марта 2019

У вас есть несколько вопросов:

#include <stdio.h>
#include <time.h>

Почему этот заголовок?

#include <stdlib.h>

int main()
{
  char ch, *ptrChFromFile; 
  int strSize;

Эта переменная должна иметь полезное начальное значение.

  ptrWordsFromFile = (char*)malloc(sizeof(char));

Нет необходимости кастовать.

  if(ptrChFromFile == NULL)
  {
     puts("COULDN'T ALLOICATE MEMORY");
     exit(EXIT_FAILURE);
  }

  while((ch = getchar()) != EOF)

getchar возвращает и int, а не char.

  {
    ptrChFromFile  = (char*)realloc(ptrChFromFile, strSize * sizeof(char)+1);

Нам нужен еще один символ, чем раньше, и дополнительное место для 0. Вы должны добавить +2 (не +1) к числу элементов: (strSize+2) * sizeof(<any type>)

Обычно вы не должны напрямую присваивать результат realloc тому же указателю. В случае неудачи вы потеряете старое значение указателя. Опять же: не требуется приведение.

    if(ptrChFromFile == NULL)
      {puts("failed to alloicate memory");}

Если это не удастся, вы не сможете продолжить! Выход из программы, как указано выше

    *ptrChFromFile = ch;

Вы помещаете символ в начало увеличенного буфера. Вы должны добавить в конце.

    strSize++;
  }

Теперь у вас есть куча символов в памяти, но нет завершения для строки.

  free(ptrChFromFile);
  return 0;
}

После исправления это выглядит так:

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

int main(void)
{
  int ch;
  char *ptrChFromFile; 
  int strSize = 0;

  ptrWordsFromFile = malloc(sizeof(char));

  if (ptrChFromFile == NULL)
  {
     puts("COULDN'T ALLOICATE MEMORY");
     exit(EXIT_FAILURE);
  }

  while ((ch = getchar()) != EOF)
  {
    ptrChFromFile = realloc(ptrChFromFile, (strSize+2) * sizeof(char));

    if (ptrChFromFile == NULL)
    {
      puts("failed to allocate memory");
      exit(EXIT_FAILURE);
    }

    ptrChFromFile[strSize] = ch;
    strSize++;
  }
  ptrChFromFile[strSize] = 0;

  // Now add detection and storing of separate words
  // (You might omit storing words that are too short)
  // Select random words and add together.

  free(ptrChFromFile);
  return 0;
}
...