#arrays #c #string
Вопрос:
У меня есть эта структура данных:
struct WordCounter
{
char *word;
int word_count;
struct WordCounter *pNext; /* Pointer to the next word counter in the list */
};
Мне это нужно, чтобы запомнить слова, прочитанные из файла, и сколько раз они встречаются. Эта структура имеет следующие функции:
int giveCounter (struct WordCounter *pCounter){ // give the occurrence of the current word in the linked list
int tempcount = pCounter -> word_count;
return tempcount;
}
int lengthOfCurrentWord(struct WordCounter *pWordCounter) // length of the current string
{
return strlen(pWordCounter->word) 1; // for the null terminator string
}
char* giveWord(struct WordCounter *pWordcounter){ // return current word of the linked list
return pWordcounter->word;
}
Что я должен сделать, так это взять все слова в списке и поместить их в массив, который может содержать их все, где каждое слово разделено терминатором.
Код такой, и после того, как я объясню, в чем проблема:
pCounter = pStart; // go to the first element in the linked list
num_car=0; // in total how much character in all words
while(pCounter != NULL){
num_car = lengthOfCurrentWord(pCounter);
pCounter = pCounter -> pNext;
}
printf("total number of chars in all words is: %d n ", num_car);
Хорошо, теперь у нас есть размер большого массива, в котором нужно сохранить все слова, разделенные терминатором.
char *exactly_word; // im forced to initialize like this and after i can give the exactly number of elements
exactly_word = malloc(sizeof(char)*num_car); // The big array
memset(exactly_word,0,num_car);
Давайте начнем копировать слово из связанного списка в большой массив:
char wordy[100] = {0}; // an array for the temp word
pCounter = pStart; // go to the first element
int indice = 0; // used for loop through single word
int indice_parole = 0; // It is used to indicate in which position of the large array to insert the character
for(int x=0; x<readed_nd_word;x ){ // readed_nd_words is the number of element in the linked list
strcat(wordy,giveWord(pCounter)); // copy the current word into wordy array
printf("WORDY: %s n",wordy); // yeah correct in each iteration
while(wordy[indice]!= 0){
printf("Character to add to exactly word: %c, at position: %d n",wordy[indice],indice_parole);
exactly_word[indice_parole] = wordy[indice]; // copy character
indice_parole ;
indice ;
}
pCounter = pCounter -> pNext; // move into next word in the linked list
memset(wordy,0,100); // reset for a new word
indice = 0;
exactly_word[indice_parole] =0; // terminator for separating words
printf("Terminator at position %d",indice_parole);
indice_parole ;
}
В чем проблема? хорошо, в цикле while точное слово заполняется правильно, но после этого кода, если я попытаюсь напечатать точное слово[0], на выходе будет:»», то же самое для позиции 1,2 точного слова. Я могу лучше объяснить проблему на примере, который я описываю с выводом:
words in the linked list:
wut 1
sut 1
ov 1
word 2
ciao 1
helo 1
cor 1
fal 1
vermalen 1
total number of chars in all words is: 43 (countered the terminator too)
WORDY: wut
Character to add to exactly word: w, at position: 0
Character to add to exactly word: u, at position: 1
Character to add to exactly word: t, at position: 2
terminator at position 3
WORDY: sut
Character to add to exactly word: s, at position: 4
Character to add to exactly word: u, at position: 5
Character to add to exactly word: t, at position: 6
terminator at position 7
Для остальных слов вывод правильный, но после этого кода, как я уже сказал, если я напечатаю точное слово[0], я получу»», такое же, как 1,2, вместо точного слова[4] = «s» от слова sut.
Если я распечатаю весь массив, у меня получится следующее: «sutovwordciaohelocorfalvermalen».
P. s. ошибка не появляется при каждом запуске, иногда она появляется, а иногда нет, когда она не появляется, слово исправлено. Есть что-то вроде непобедимого поведения, которого я не вижу? пожалуйста, помогите 🙁
Комментарии:
1. Как общее замечание (хотя и не является причиной ошибок),
sizeof(char)
всегда1
по определению (размеры указаны в единицах символов), поэтому умножение не требуется. (Если вы хотите, чтобы тип был четким, ИМО, лучше использовать шаблонstr = malloc(sizeof(*str) * len)
)2. @Arkku да, я вижу ошибку с позицией, но почему отсутствуют первые 3 символа? И почему поведение такое странное?
3. В СТОРОНУ: Вы могли бы измениться
strcat(wordy,giveWord(pCounter));
наstrcpy(wordy,giveWord(pCounter));
. Затемchar wordy[100] = {0};
может быть измененchar wordy[100];
иmemset(wordy,0,100);
может быть удален.4. @IanAbbott, это и есть ошибка?
5. Вместо того, чтобы печатать массив в виде текста, попробуйте напечатать каждый символ, например, в шестнадцатеричном формате, например, с
printf(" x", exactly_word[index])
помощью . Возможно, какой-то управляющий персонаж возится с вашим терминалом.
Ответ №1:
В комментарии вы показываете нам шестнадцатеричный дамп exactly_word
to be
01 00 00 00 73 75 74 00 6f 76 00 77 6f 72 64 ...
это указывает на то, что у вас есть перезапись в памяти первых 3 (возможно, 4) байтов exactly_word
. Похоже, что целочисленное значение 1
было записано в начало массива (малый конец), но это всего лишь предположение, потому что: этого не происходит в опубликованном коде. Это должно быть в коде, который вы нам не показывали.
Тем не менее, ваш текущий код слишком сложен. Упростите это, как:
exactly_word = malloc(num_car);
char* dst = exactly_word;
pCounter = pStart;
while(pCounter){
strcpy(dst, giveWord(pCounter));
dst = lengthOfCurrentWord(pCounter); // which includes termination char
pCounter = pCounter -> pNext;
}
Комментарии:
1. Для опубликованного кода я никогда не использую точное слово, поэтому его использование начинает формировать опубликованный код, после этого я просто печатаю точное слово, и именно здесь происходит волшебство, у меня много кода, исключающего это, но возможно ли, что предыдущий код повлияет на рассматриваемый код?
2. Я что-то пропустил, мое точное слово объявлено так: char *exactly_word; это проблема? Я вынужден инициализировать таким образом, потому что я программирую в mpi, и второй процессор (ведомый) не может знать, насколько точно размерен_слово при запуске. Поэтому я даю измерение в той части кода, когда у меня есть num_car, но для других вещей мне нужно, чтобы оно было объявлено до и заполнено после @4386427
3. @GabrielePisapia Я не могу отлаживать код, который ты мне не показываешь!!! Опубликованный код работает нормально. Видишь ideone.com/QmvugI Поэтому я могу только повторить: ваша ошибка в коде, который не опубликован
4. @GabrielePisapia Теперь вы упоминаете mpi . Я мало что знаю об этом, но AFAIK, это какая-то многопоточная среда, не так ли? В любом случае это может быть вероятным источником вашей ошибки: ваш опубликованный код работает нормально