Этот вопрос является продолжением этот вопрос.
Вот код:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
char *ptrChFromFile;
char **ptrWords;
int strSize = 1;
int i;
int j = 0;
int numberOfWords = 1;
ptrChFromFile = malloc(sizeof(char));
if (ptrChFromFile == NULL)
{
puts("COULDN'T ALLOICATE MEMORY");
exit(EXIT_FAILURE);
}
while ((ch = getchar()) != '\n')
{
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;
ptrWords = malloc(sizeof(char*) * numberOfWords); //creates number of slots in ptr
if (ptrWords == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < numberOfWords; i++) // allocates number of bytes in each slot.
{
ptrWords[i] = malloc(sizeof(char*)* strSize);
if (ptrWords[i] == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < strSize; i++)
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j] = &ptrChFromFile[i];
}
else
{
ptrWords[j] = 0;
j++;
}
}
for (i = 0; i < numberOfWords; i++) // free's each slot in ptrWords
{
free(ptrWords[i]);
}
free(ptrChFromFile);
free(ptrWords);
return 0;
}
Я пытаюсь динамически выделить указатель на двойной символ ptrWords. Позвольте мне объяснить ход моих мыслей:
ptrWords = malloc(sizeof(char*) * numberOfWords); //creates number of slots in ptr
Это создает количество слотов (индексов) в ptrWords. поэтому, если у меня есть 3 слова, ptrWords должен выглядеть так:
ptrWords[индекс 0]
ptrWords[индекс 1]
ptrWords[индекс 2]
for (i = 0; i < numberOfWords; i++) // allocates number of bytes in each slot.
{
ptrWords[i] = malloc(sizeof(char*)* strSize);
if (ptrWords[i] == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
}
Этот цикл for выделяет каждому слоту в ptrWords память, равную общему количеству символов во входном файле. Таким образом, если во входном файле всего 26 символов, то каждому слоту в ptrWords будет отведено 26 байтов.
ptrWords[index 0] имеет 26 байт памяти
ptrWords[index 1] имеет 26 байт памяти
ptrWords[index 2] имеет 26 байт памяти
Я думаю, что мое выделение памяти для ptrWords правильное, но я не уверен.
for (i = 0; i < strSize; i++)
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j] = &ptrChFromFile[i];
}
else
{
ptrWords[j] = 0;
j++;
}
}
Этот цикл for должен брать символы из ptrChFromFile и сохранять их в ptrWords как отдельные слова. Моя логика с циклом выглядит следующим образом:
1) Пока ch не равен пробелу, возьмите этот символ и сохраните его в первой позиции (индекс 0) ptrWords.
2) если ch действительно равен пробелу, поместите на его место завершающий символ ('\0'), затем увеличьте j на 1, чтобы перейти к следующему индексу в ptrWords для сохранения следующего слова.
Я использовал отладчик, чтобы выполнить код, но я все еще не могу понять, что не так, поэтому любая помощь будет оценена по достоинству.
Спасибо
Моя реализация:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
char *ptrChFromFile;
char **ptrWords;
int strSize = 1;
int i;
int j = 0;
int k = 0;
int numberOfWords = 1;
ptrChFromFile = malloc(sizeof(char));
if (ptrChFromFile == NULL)
{
puts("COULDN'T ALLOCATE MEMORY");
exit(EXIT_FAILURE);
}
while ((ch = getchar()) != '\n')
{
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;
ptrWords = malloc(sizeof(char*) * numberOfWords); //creates number of slots in ptrWords
for (i = 0; i < numberOfWords; i++) // allocates number of bytes in each slot.
{
ptrWords[i] = malloc(sizeof(char*)* strSize);
if (ptrWords[i] == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
}
if (ptrWords == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < strSize; i++)
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j][k++] = ptrChFromFile[i];
}
else
{
ptrWords[j][k] = 0;
ptrWords[j] = realloc(ptrWords[j], k+1);
j++;
k = 0;
}
}
printf("%s", ptrWords[0]);
free(ptrChFromFile);
free(ptrWords);
return 0;
}
пример ввода: "привет"
вывод: привет
Привет
Текущая версия кода:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int getStrLength(char *word)
{
int lengthOfWord = 0;
int i;
for (i = 0; word[i] != 0; i++)
{
lengthOfWord++;
}
return lengthOfWord;
}
int compareWords(char *firstWord, char *secondWord)
{
while (*firstWord && *firstWord == *secondWord)
{
firstWord++;
secondWord++;
}
return *firstWord - *secondWord;
}
int main(void)
{
int ch;
char *ptrChFromFile;
char **ptrWords;
char **ptrCrunchWord;
int strSize = 0;
int i;
int j = 0;
int k = 0;
int numberOfWords = 0;
int defaultWordLength = 6;
srand(time(0)); // Use current time as seed for random generator
ptrChFromFile = malloc(sizeof(char));
if (ptrChFromFile == NULL)
{
puts("COULDN'T ALLOCATE MEMORY");
exit(EXIT_FAILURE);
}
while ((ch = getchar()) != '\n') // this reads in chars from file to ch variable
{
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++;
}
numberOfWords++;
ptrChFromFile[strSize] = 0;
ptrWords = malloc(sizeof(char*) * numberOfWords); //creates number of slots in ptrWords
if (ptrWords == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < numberOfWords; i++) // allocates number of bytes in each slot.
{
ptrWords[i] = malloc(strSize);
if (ptrWords[i] == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < strSize; i++) // This inserts words in ptrWords separated by spaces.
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j][k++] = ptrChFromFile[i];
}
else
{
ptrWords[j][k] = 0;
ptrWords[j] = realloc(ptrWords[j], k+1);
j++;
k = 0;
}
}
// terminate and resize last word
ptrWords[j][k] = 0;
ptrWords[j] = realloc(ptrWords[j], k+1);
j = 0;
k = 0;
// crunchWord code starts here:
ptrCrunchWord = malloc(sizeof(char*));
ptrCrunchWord[0] = malloc(strSize);
if (ptrCrunchWord == NULL || ptrCrunchWord[0] == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < numberOfWords; i++)
{
int randomIndex = rand() % numberOfWords;
if (compareWords(ptrCrunchWord[i], ptrWords[randomIndex]) != 0)
{
if (getStrLength(ptrWords[randomIndex]) >= defaultWordLength)
{
ptrCrunchWord[i] = ptrWords[randomIndex]; // main problem here
}
}
}
printf("The crunch word is: %s", ptrCrunchWord[0]);
for (i = 0; i < numberOfWords; i++) // Free's allocated memory from all pointers
{
free(ptrWords[i]);
}
free(ptrChFromFile);
free(ptrWords);
free(ptrCrunchWord[0]);
free(ptrCrunchWord);
return 0;
}
Это самый актуальный код. Последнее, что мне нужно сделать, это сохранить все слова, которые больше или равны шести, в ptrCrunchWord. Моя основная проблема заключается в выделении места в ptrCrunchWord[0] для последнего ключевого слова и сохранении слов в индексе 0. Я выделяю место только для элемента, потому что в ptrCrunchWord будет храниться только одно слово. Я написал два метода: один проверяет длину каждого слова, а другой метод сравнивает два слова, чтобы увидеть, совпадают ли они. Наконец, мне нужно напечатать ключевое слово без пробелов.
Спасибо
ptrWords
, но в следующем цикле эти указатели заменяются указателями наptrChFromFile
. Вы имели в виду скопировать строки из одного массива в другой вместо того, чтобы назначать указатели? - person Barmar   schedule 10.03.2019free(ptrWords[i])
, так как эти указатели не были возвращеныmalloc/realloc
. - person Barmar   schedule 10.03.2019numberOfWords
, который является общим количеством слов в файле. Это, вероятно, неверно, так как включает слишком короткие слова. Кстати: Почему вы вообще храните слова, которые недостаточно длинны в вашем массиве слов? - person Gerhardh   schedule 13.03.2019