2013-03-30 2 views
0

Я читаю файл и добавляю каждый символ в массив. Затем я разбиваю эти символы на слова, удаляя пробелы и другие несущественные символы. Теперь, чтобы работать с каждым словом индивидуально, я хотел бы добавить каждое слово в собственный массив. Есть какой-либо способ сделать это? Я попытался добавить местоположение памяти начала каждого слова, но он продолжает давать мне адрес памяти самого начала массива. Проблема заключается в том, что в приведенном ниже коде переменная с именем «buffer» перезаписывает себя новым словом с каждой итерацией цикла while. Мне нужно иметь возможность ссылаться на каждое слово, чтобы вставить его в связанный список. Вот то, что я до сих пор:C Как ссылаться на различные ячейки памяти в одном массиве

#include <stdio.h> 
#include <ctype.h> 

int main(int argc, char **argv) { 
char buffer[1024]; 
int c; 
size_t n = 0; 

FILE *pFile = stdin; 

pFile = fopen(argv[1], "r"); 
if (pFile == NULL) perror("Error opening file"); 
    else { 
     while((c = fgetc(pFile)) != EOF) { 

      if (isspace(c) || ispunct(c)) { 

       if (n > 0) { 
        buffer[n] = 0; 
        printf("read word %s\n", buffer); 
        n = 0; 
       } 
      } else { 
       buffer[n++] = c; 
      } 
     } 
     if (n > 0) { 
      buffer[n] = 0; 
      printf("read word %s\n", buffer); 
     } 
     fclose(pFile); 
    } 
return 0; 
} 

Если я даю файл, содержащий символы «это тест документ, который содержит слово для этого упражнения», следующий производятся:

read word This 
read word is 
read word a 
read word test 
read word document 
read word that 
read word holds 
read word words 
read word for 
read word this 
read word exercise 
+1

Там нет связанного списка в коде, но как только вы его добавите, вы можете использовать 'strcpy' для копирования текущего содержимого' buffer' в новый элемент связанного списка. – jogojapan

ответ

1

Похоже, у вас есть хорошее начало. То, что вы делаете, успешно читает все слова в один массив по одному и перезаписывает их каждый раз.

Проблема в том, что в приведенном ниже коде переменная с именем «buffer» перезаписывает себя новым словом с каждой итерацией цикла while.

Конечно, делает:

 if (n > 0) { 
      buffer[n] = 0; // this line terminates each string 
      printf("read word %s\n", buffer); 
      n = 0;   // this line resets the array so you overwrite with the next 
          // word 
    } 

Так что в данный момент нужно просто поместить эти слова в свой связный список, а не перезаписывать их. Вы можете хранить их все в массиве (если это достаточно долго), но зачем беспокоиться, когда вам просто нужно отнять их? вам действительно нужно сделать это, замените эту строку:

printf("read word %s\n", buffer); 

с кодом для добавления слова в свой список.В основном вам нужно какое-то структура «узел», в самом общем смысле, что нужно сделать что-то вроде:

struct node{ 
    char * word;  // place to add the word 
    struct node *next; // pointer to the next node 
}; 

Вам просто нужно, чтобы получить некоторую память для каждого узла и каждую строку в узлах, как вы идти, следующий код предполагает, что вы есть головной узел, указывающий на первый узел в связанном списке, и что у вас есть указатель на текущий узел, который начинается в голове:

cur->next = malloc(sizeof(node));   // assign memory for a new node 
cur = cur->next;       // move current to the next node 
cur->word = malloc(sizeof strlen(buffer)); // assign memory for the word 
cur->next = NULL;       // set the next pointer to NULL 
strcpy(cur->word, buffer);     // copy the word from the buffer 
              // to your list 
1

Если все вам нужно сохранить строку, которую вы прочитали, затем вы можете использовать strdup (man strdup для получения дополнительной информации), чтобы сделать копию буфера, а затем сохранить указатель в массиве или связанном списке, как вы упомянули.

Имейте в виду, что strdup использует malloc для распределения памяти для каждой строки, и вы должны освободить эту память самостоятельно, когда строки больше не нужны. Кроме того, многократное использование malloc для выделения многих небольших блоков памяти может быть дорогостоящим, поэтому используйте с осторожностью!

1

buffer по-прежнему является указателем, то есть применяется арифметика указателя. Вы пишете 0 внутри buffer всякий раз, когда вы сталкиваетесь с концом слова - это хорошо. Теперь все, что вам нужно сделать, чтобы ваше следующее слово в отдельном массиве только FastForward buffer в следующую свободную позицию:

buffer += n; 

Чтобы сделать это выглядеть аккуратнее, можно отказаться от n вообще, есть buffer++ везде и скопировать следующий характер слова, как *buffer = c.

Затем каждое слово сидит в своем собственном массиве и не перекрывается. Вы можете использовать указатель на начало слова для хранения в связанном списке. Вы можете использовать обычные строковые функции (например, strlen), и их вывод не будет страдать от пакетной упаковки строк в память. Это возможно, потому что вы добавили 0 в конце каждого сохраненного слова.

+0

Таким образом, оператор будет равен: if (n> 0) { \t buffer [n] = 0; // Когда достигнут конец слова, сохраните 0. \t printf («читать слово% s,% d \ n», buffer, mem_position); \t буфер [n] + = n; \t n = 0; } Где «mem_position» - адрес памяти. Конечно, это неверно ..: s – drizzy

+0

'buffer [n] + = n' означает принимать значение, хранящееся в адресе' buffer + n', и добавить 'n' к нему. Чтобы перейти к следующему слову, вам нужно обновить сам указатель –

Смежные вопросы