在c中动态分配双指针
dynamic allocate double pointer in c
这个问题是 的延续。
代码如下:
#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[索引 0] 有 26 字节的内存
ptrWords[索引 1] 有 26 字节内存
ptrWords[索引 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 不等于 a space 取该字符并将其存储在 ptrWords 的第一个位置(索引 0)。
2) 如果 ch 确实等于 space 则在其位置放置一个终止字符 ('\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;
}
示例输入:"hey there"
输出:你好
¿嘿
当前代码版本:
#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] 中为最后一个紧缩词分配 space 并将这些词存储在索引 0 中。我只为元素分配 space 因为 ptrCrunchWord 中只会存储一个词.我写了两种方法,一种检查每个单词的长度,另一种方法比较两个单词看它们是否相同。最后,我需要打印没有 spaces.
的紧缩词
谢谢
这个循环是错误的:
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
以添加 space 作为尾随空值)。
为 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;
}
我会尝试展示一个更像您的初始版本的版本。
我将跳过读取文件的部分。当然,需要应用 Barmar 提到的与 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);
}
#define MIN_LENGTH 6
int start = 0, end = 0;
numWords = 0; // Start counting again. Only handle words long enough.
for (i = 0; i < strSize; i++) // Walk the inital array again
{
if (ptrChFromFile[i] == ` `)
{
end = i;
if (end - start >= MIN_LENGTH)
{ // Found a word? Store address and terminate.
ptrWords = &ptrChFromFile[start];
ptrChFromFile[i] = 0;
numWords ++;
}
// Words that are too short are ignored
// Also if a second space follows, no new word is counted...
// Prepare for new word starting at next position.
start = end = i+1;
}
}
// Maybe one more word without a space afterwards?
end = i;
if (end - start >= MIN_LENGTH)
{ // Found a word? Store address and terminate.
ptrWords = &ptrChFromFile[start];
// ptrChFromFile[i] = 0; This word is already terminated.
numWords ++;
}
ptrWords = realloc(sizeof(char*) * numberOfWords); // Reduce size to only hold long words
// Decide number n how many words shall be concatenated
// Use scanf or any other mechanism...
int n = numWords / 2;
为了选择单词,我将使用一个数组来仅保存每个单词的索引。
它用索引 0..n-1 初始化。
对于每个选定的单词,我将索引移动到数组中的第一个位置,并将(前)第一个元素放到选定的位置。
此后,前 n 个元素保存随机索引值。
由于在每一步中随机选择的范围都在减小,因此不可能出现重复。
不需要比较单词。
// Create an array to hold the indices of chosen words.
int selectedWords[n];
for (i = 0; i < n; i++)
selectedWords[i] = i;
// Select n words, store index.
srand(time(0));
for (i = 0; i < n; i++)
{
// Pick random element 0..n
int elem = rand()%(n-i);
int temp;
temp = selectedWords[i+elem];
selectedWords[i+elem] = selectedWords[i];
selectedWords[i] = temp;
}
// This first n entries hold the selected words.
// How long will it be in the end?
size_t len = 0;
for (i = 0; i < n; i++)
{
len += strlen(ptrWords[selectedWords[n]]);
}
// Get memory for final result...
char *resultWord = malloc(len+1);
// TODO: check for NULL
resultWord[0] = 0;
for (i = 0; i < n; i++)
{
strcat(resultWord, ptrWords[selectedWords[n]]);
}
printf("%s\n", resultWord)
free(ptrChFromFile);
free(ptrWords);
free(resultWord);
return 0;
}
代码未经编译或测试。
这个问题是
代码如下:
#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[索引 0] 有 26 字节的内存
ptrWords[索引 1] 有 26 字节内存
ptrWords[索引 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 不等于 a space 取该字符并将其存储在 ptrWords 的第一个位置(索引 0)。
2) 如果 ch 确实等于 space 则在其位置放置一个终止字符 ('\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;
}
示例输入:"hey there"
输出:你好
¿嘿
当前代码版本:
#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] 中为最后一个紧缩词分配 space 并将这些词存储在索引 0 中。我只为元素分配 space 因为 ptrCrunchWord 中只会存储一个词.我写了两种方法,一种检查每个单词的长度,另一种方法比较两个单词看它们是否相同。最后,我需要打印没有 spaces.
的紧缩词谢谢
这个循环是错误的:
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
以添加 space 作为尾随空值)。
为 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;
}
我会尝试展示一个更像您的初始版本的版本。
我将跳过读取文件的部分。当然,需要应用 Barmar 提到的与 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);
}
#define MIN_LENGTH 6
int start = 0, end = 0;
numWords = 0; // Start counting again. Only handle words long enough.
for (i = 0; i < strSize; i++) // Walk the inital array again
{
if (ptrChFromFile[i] == ` `)
{
end = i;
if (end - start >= MIN_LENGTH)
{ // Found a word? Store address and terminate.
ptrWords = &ptrChFromFile[start];
ptrChFromFile[i] = 0;
numWords ++;
}
// Words that are too short are ignored
// Also if a second space follows, no new word is counted...
// Prepare for new word starting at next position.
start = end = i+1;
}
}
// Maybe one more word without a space afterwards?
end = i;
if (end - start >= MIN_LENGTH)
{ // Found a word? Store address and terminate.
ptrWords = &ptrChFromFile[start];
// ptrChFromFile[i] = 0; This word is already terminated.
numWords ++;
}
ptrWords = realloc(sizeof(char*) * numberOfWords); // Reduce size to only hold long words
// Decide number n how many words shall be concatenated
// Use scanf or any other mechanism...
int n = numWords / 2;
为了选择单词,我将使用一个数组来仅保存每个单词的索引。 它用索引 0..n-1 初始化。 对于每个选定的单词,我将索引移动到数组中的第一个位置,并将(前)第一个元素放到选定的位置。 此后,前 n 个元素保存随机索引值。 由于在每一步中随机选择的范围都在减小,因此不可能出现重复。 不需要比较单词。
// Create an array to hold the indices of chosen words.
int selectedWords[n];
for (i = 0; i < n; i++)
selectedWords[i] = i;
// Select n words, store index.
srand(time(0));
for (i = 0; i < n; i++)
{
// Pick random element 0..n
int elem = rand()%(n-i);
int temp;
temp = selectedWords[i+elem];
selectedWords[i+elem] = selectedWords[i];
selectedWords[i] = temp;
}
// This first n entries hold the selected words.
// How long will it be in the end?
size_t len = 0;
for (i = 0; i < n; i++)
{
len += strlen(ptrWords[selectedWords[n]]);
}
// Get memory for final result...
char *resultWord = malloc(len+1);
// TODO: check for NULL
resultWord[0] = 0;
for (i = 0; i < n; i++)
{
strcat(resultWord, ptrWords[selectedWords[n]]);
}
printf("%s\n", resultWord)
free(ptrChFromFile);
free(ptrWords);
free(resultWord);
return 0;
}
代码未经编译或测试。