Как читать по всему слову, а не только по первому символу? - PullRequest
3 голосов
/ 23 июня 2019

Я пишу метод на C, в котором у меня есть список слов из файла, который я перенаправляю из stdin. Однако, когда я пытаюсь прочитать слова в массив, мой код будет выводить только первый символ. Я понимаю, что это связано с проблемой приведения типов char и char *.

Хотя я пытаюсь не использовать ни одну из функций из string.h, я попытался выполнить итерацию и подумал о написании своей собственной функции strcpy, но я запутался, потому что мои данные поступают из файла, которым я являюсь перенаправление со стандартного ввода. Переменная numwords вводится пользователем в основном методе (не показан).

Я пытаюсь отладить эту проблему с помощью dumpwptrs, чтобы показать мне, что выводится. Я не уверен, что в коде заставляет меня получать неправильный вывод - это то, как я читаю словами массив массива, или я неправильно указываю на него с помощью wptrs?

//A huge chunk of memory that stores the null-terminated words contiguously
char chunk[MEMSIZE]; 

//Points to words that reside inside of chunk
char *wptrs[MAX_WORDS]; 

/** Total number of words in the dictionary */
int numwords;
.
.
.
void readwords()
{
  //Read in words and store them in chunk array
  for (int i = 0; i < numwords; i++) {
    //When you use scanf with '%s', it will read until it hits
    //a whitespace
    scanf("%s", &chunk[i]);
    //Each entry in wptrs array should point to the next word 
    //stored in chunk
    wptrs[i] = &chunk[i]; //Assign address of entry
  }
}

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

Не используйте повторно char chunk[MEMSIZE];, использованный для предыдущих слов.

Вместо этого используйте следующую неиспользуемую память.

char chunk[MEMSIZE]; 
char *pool = chunk; // location of unassigned memory pool

    // scanf("%s", &chunk[i]);
    // wptrs[i] = &chunk[i];
    scanf("%s", pool);
    wptrs[i] = pool;
    pool += strlen(pool) + 1;  // Beginning of next unassigned memory

Надежный код проверяет возвращаемое значение scanf() и убедитесь, что i, chunk не превышают лимиты.

Я бы выбрал решение fgets(), если слова вводятся в строку за раз.

char chunk[MEMSIZE]; 
char *pool = chunk;

// return word count
int readwords2() {
  int word_count;
  // limit words to MAX_WORDS
  for (word_count = 0; word_count < MAX_WORDS; word_count++) {
    intptr_t remaining = &chunk[MEMSIZE] - pool;
    if (remaining < 2) {
      break; // out of useful pool memory
    }
    if (fgets(pool, remaining, stdin) == NULL) {
      break; // end-of-file/error
    }
    pool[strcspn(pool, "\n")] = '\0'; // lop off potential \n
    wptrs[word_count] = pool;
    pool += strlen(pool) + 1;
  }
  return word_count;
}
0 голосов
/ 25 июня 2019

В то время как я бросаю себе вызов не использовать ни одну из функций из string.h, ...

Лучший способ испытать себя, чтобы не использовать ни одну из функций из string.h состоит в том, чтобы написать их самостоятельно, а затем использовать их.

ваша программа считывает следующее слово в позиции i -esim буфера chunk, поэтому вы получаете первые буквы каждого слова (до тех пор, пока i не превысит размер chunk), каждый раз, когда вы читаете, вы перезаписываете второй и остальные символы последнего слова на символы только что прочитанного.Затем вы помещаете все указатели в wptrs, чтобы они указывали на эти места, делая невозможным различение конца одной строки за другой (вы переписали все нулевые терминаторы, оставив только последний), так что вы получите первыйстрока со всеми первыми буквами ваших слов, кроме последней, что завершено.тогда вторая будет иметь ту же строку, но начинающуюся со второй ... затем третья .... и т. д.

Создайте свою собственную версию strdup(3) и используйте chunk для временного хранения строки... затем сделайте динамически распределенную копию строки с вашей версией strdup(3) и сделайте указатель, чтобы указать на нее .... и т. д.

Наконец, когда вы закончите, просто освободите всевыделенные строки и voilà !!

Кроме того, это очень важно: прочитайте Как создать пример Minimal, Complete и Verifiable , так как очень часто вашв коде отсутствуют некоторые ошибки, которые вы устранили из опубликованного кода (вы обычно не знаете, где находится ошибка, или вы бы ее исправили, и здесь нет вопросов, верно?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...