此问题是this question的继续。
这是代码:
#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不等于空格,就可以将该字符存储在ptrWords的第一个位置(索引0)。
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;
}
这是最新的代码。我需要做的最后一件事是将所有大于或等于6的单词存储在ptrCrunchWord中。我的主要问题是在ptrCrunchWord [0]中为最后一个紧缩词分配空间,并将这些词存储在索引0中。我仅在元素中分配空间,因为ptrCrunchWord中将仅存储一个词。我编写了两种方法,一种检查每个单词的长度,另一种方法比较两个单词以查看它们是否相同。最后,我需要打印紧缩单词,不带空格。
谢谢
最佳答案
此循环是错误的:
for (i = 0; i < strSize; i++)
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j] = &ptrChFromFile[i];
}
else
{
ptrWords[j] = 0;
j++;
}
}
您不应该重新分配
ptrWords[j]
,应该将其复制到上一个循环中分配的内存中。您需要另一个变量k
来保存要在目标数组中分配的索引。int k = 0;
for (i = 0; i < strSize; i++)
{
if (ptrChFromFile[i] != ' ')
{
ptrWords[j][k++] = ptrChFromFile[i];
}
else
{
ptrWords[j][k] = 0;
j++;
k = 0;
}
}
您还为分配给
ptrWords
的内存量大大增加了。每个单词分配的字符与文件的整个大小一样多。到达每个单词的末尾时,在分配了ptrWords[j][k] = 0
之后,可以使用以下方法将该分配缩小为单词的大小:ptrWords[j] = realloc(ptrWords[j], k+1);
另一个问题是您初始化了
strSize = 1;
。这导致您将输入的第一个字符放入ptrChFromFile[1]
而不是ptrChFromFile[0]
,因此第一个单词无法正确复制。应该将其初始化为int strSize = 0
。但是要调整此更改,您需要将所有ptrChFromFile
分配增加1个字符(或在末尾执行另一个realloc
来为尾随的null添加空间)。为
ptrWords[i]
分配内存时,请勿将其乘以sizeof(char *)
。 ptrWords
是指针数组,ptrWords[i[
是char
数组。完成将初始输入读取到
ptrChFromFile
的循环后,需要递增numberOfWords
。否则,您将不会计算换行符之前的最后一个单词。您不应该在释放所有
ptrWords[i]
的末尾删除循环。您使用malloc
分配的所有内容都需要释放。这是工作版本:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
char *ptrChFromFile;
char **ptrWords;
int strSize = 0;
int i;
int j = 0;
int k = 0;
int numberOfWords = 1;
ptrChFromFile = malloc(2);
if (ptrChFromFile == NULL)
{
puts("COULDN'T ALLOCATE MEMORY");
exit(EXIT_FAILURE);
}
while ((ch = getchar()) != '\n')
{
ptrChFromFile = realloc(ptrChFromFile, (strSize+2));
if (ptrChFromFile == NULL)
{
puts("failed to allocate memory");
exit(EXIT_FAILURE);
}
if (ch == ' ')
{
numberOfWords++;
}
ptrChFromFile[strSize] = ch;
strSize++;
}
numberOfWords++; // increment for last word
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(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\n", ptrWords[0]);
for (i = 0; i < strSize; i++) {
free(ptrWords[i]);
}
free(ptrChFromFile);
free(ptrWords);
return 0;
}