当你不知道用户会输入多少单词时,如何动态分配2d数组



我想制作一个程序,将输入的单词存储到2D数组中(可以是你想要的任意数量(,一旦你输入单词"end",程序就应该退出while循环。例如,如果我输入以下内容:

word1
word2
longer-word
end

那么输出应该是:

List of words are:
word1
word2
longer-word

但问题是,我显然不知道用户会输入多少单词(我动态分配了2d数组5*20,所以最多5个单词(,那么";正确的";动态分配2D数组的方式,我是否必须在每次用户输入新词时以某种方式重新分配?我真的不知道该怎么做。

这是一个代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** allocate(int n, int m) {
char** arr = (char**)malloc(sizeof(char*) * n);
for (int i = 0; i < n; i++)
arr[i] = (char*)malloc(sizeof(char) * m);
return arr;
}
void print(char** words, int n, int m) {
printf("List of words: n");
for (int i = 0; i < n; i++) {
printf("%sn", words[i]);
}
}
int main() {
char** words = allocate(5,20);
char input[20];
int index = 0;
while ( strcmp("end", input) ) {
scanf(" %s", input);
if (strcmp("end", input) != 0) {
strcpy(words[index], input);
index++;
}
}

print(words, 5, 20);
return 0;
}

我还注意到,当你输入两个单词(带空格(时,它会分别输出这两个单词,那么我该如何防止这种情况呢?

您需要的是猜测一个合理的大小并进行分配。当你分配你的单词时,你需要检查你的极限是否没有达到。如果它会被击中,那么你需要用更大的尺寸realloc你的数组。一个常见的策略是每次将大小增加一倍。

c/c++中的数组不能有变量,所以这个问题不能像这样解决,你也可以把这个2d数组想象成字符串的1d数组。这就是我提出的解决方案:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_SIZE 20
char **allocate(int n, int m) {
char **arr = (char **) malloc(sizeof(char *) * n);
for (int i = 0; i < n; i++)
arr[i] = (char *) malloc(sizeof(char) * m);
return arr;
}
/**
* first we will check if the count + 1 equal the size and if true we will create new array with a size
* of size*2 and then move all the words to the new array, if it does not equal then we will copy the new word to the
* array, also the array is passed by pointer so any change on this array in this scope it will change in the main.
* @param words the words array that has all the words
* @param newWord the new word to be inserted
* @param index the index to insert the nwe word
* @param size the size of the current array
* @param wordSize the word size the second dimension in the array
* @return will return a 2d array.
*/
char** addNewWord(char **words, char *newWord, int index, int *size, int wordSize) {
if (index == *size) {
int newSize = *size * 2;
char **newArray = allocate(newSize, wordSize);
for (int i = 0; i < *size; i++) {
strcpy(newArray[i], words[i]);
}
strcpy(newArray[index], newWord);
*size = newSize;
return newArray;
}
strcpy(words[index], newWord);
return words;
}
void print(char **words, int n) {
printf("List of words: n");
for (int i = 0; i < n; i++) {
printf("%sn", words[i]);
}
}
int main() {
int size = 5;
char **words = allocate(size, MAX_WORD_SIZE);
char input[MAX_WORD_SIZE];
int index = 0;
while (1) {
fgets(input, MAX_WORD_SIZE, stdin);
input[strcspn(input,"n")] = 0;
if (strcmp("end", input) != 0) {
words = addNewWord(words, input, index, &size, MAX_WORD_SIZE);
index++;
} else {
break;
}
}
print(words, index);
return 0;
}

我这样做的方式是,我创建了一个用于添加新词的新函数,如果索引等于数组的大小,我创建一个新数组,并将第一个数组的内容复制到第二个数组,此外,我已经使用指针传递了大小变量,这样我就可以在函数中更改它,这种更改也将在main中更改。

--编辑:我已经将打印从打印(单词,大小(改为打印(单词、索引(

--编辑2:将scanf()更改为fgets,因为它更安全,感谢chux-在笔记中恢复Monica,以下是scanf危险的原因。

最新更新