Я пытаюсь добавить слова из двух файлов (их может быть больше) в структуру. Это работает. Однако у меня есть возможность удалить некоторые слова (которые находятся в stop.txt ) из структуры. Это приводит к неправильному выводу, когда он активирован и два файла находятся в нем.
Например, в test.txt У меня есть несколько случайных строк:
kiio
luio
kiio
ohaio
lol
В test1.txt :
vola
kiio
kiio
haio
lol
и stop.txt :
luio
kiio
Вывод при активации remove_word
:
lol test.txt [1] {5}
lol %~ [1] {5}
lol %~ [1] {5}
luio test.txt [1] {2}
ohaio test.txt [1] {4}
vola test1.txt [1] {1}
Когда это не так:
kiio test.txt [2] {1,3} I need to have two nodes with the same word but different `fileno`
kiio test1.txt [2] {2,3}
lol test.txt [1] {5}
lol test1.txt [1] {5}
luio test.txt [1] {2}
ohaio test.txt [1] {4}
vola test1.txt [1] {1}
haio test1.txt [1] {4}
Я думаю, что проблема в функции remove_word
, но я не уверен, потому что она работает (удаляет слова) только для одного файла.
Вот определения структуры:
typedef struct _word {
char *s; /* the word */
int count; /* number of times word occurs */
int *line_numbers; // Array of line numbers
int num_line_numbers; // Size of the array of line numbers
char *fileno;
} word;
// Creating a struct to hold the data. I find it's easier
typedef struct {
word *words; // The array of word structs
int num_words; // The size of the array
} word_list;
remove_word
Функция:
void remove_word(word_list *words, const char *word_to_delete) {
for (int i = 0; i < words->num_words; i++) {
if (0 == strcmp(words->words[i].s, word_to_delete)) {
// TODO: handle special case where there is only 1 word in list
// Calc number of words after found word
int number_of_words_to_right = words->num_words - i - 1;
// Free mem
free(words->words[i].s);
free(words->words[i].line_numbers);
free(words->words[i].fileno);
// Copy remaining words
memcpy(&words->words[i], &words->words[i + 1], sizeof(word) * number_of_words_to_right);
// Resize the array (technically not required)
word *tmp = realloc(words->words, sizeof(word) * --words->num_words);
if (NULL == tmp) exit(0);
words->words = tmp;
}
}
return;
}
Main:
int main() {
int i, n, m;
int option = 0;
n = 0;
FILE *file = fopen("test.txt", "r");
word_list *words = malloc(sizeof(word_list));
if (NULL == words)
exit(0);
memset(words, 0, sizeof(word_list));
char s[1000];
int line_number = 1;
while (fgets(s, sizeof(s), file)) {
char *word = strtok(s, " ");
while (word != NULL) {
size_t len = strlen(word);
if (len > 0 && word[len - 1] == '\n')
word[--len] = 0;
insert_word(words, word, line_number, "test.txt");
word = strtok(NULL, " ");
}
line_number += 1;
}
fclose(file);
FILE *file1 = fopen("test1.txt", "r");
line_number = 1;
while (fgets(s, sizeof(s), file)) {
char *word = strtok(s, " ");
while (word != NULL) {
size_t len = strlen(word);
if (len > 0 && word[len - 1] == '\n')
word[--len] = 0;
insert_word(words, word, line_number, "test1.txt");
word = strtok(NULL, " ");
}
line_number += 1;
}
fclose(file1);
if (option == 0) {
FILE *stopfile = fopen("stop.txt", "r"); /* should check the result */
char fline[256];
while (fgets(fline, sizeof(fline), stopfile)) {
remove_word(words, fline);
}
fclose(stopfile);
}
printlist(words);
for (int i = 0; i < words->num_words; i++) {
free(words->words[i].s);
free(words->words[i].line_numbers);
free(words->words[i].fileno);
}
free(words->words);
free(words);
}