好吧,我已经为此付出了很多努力,研究了很多问题,但我还不能完全弄清真相。希望你能在这里对我的问题有所了解!
int main(int argc, char *argv[]){
char read[50];
char *string[10];
while(1){
fgets(read,sizeof read, stdin);
int t = 0; //ticks whenever a non-whitespace char is read
int pos = 0; //keeps track of position in string array
int i;
int j;
for(i = 0; i < sizeof read; i++){
if(isspace(read[i]) && t != 0){
string[pos] = malloc((t+1) * (sizeof(char)));
// int z;
// for(z = 0; z < sizeof string[pos]; z++){
// string[pos][z] = ' ';
// }
for(j = 0; j < t; j++){
string[pos][j] = read[i-(t-j)];
}
t = 0;
pos++;
}
else if(!isspace(input[i])) t++;
}
int k;
for(k = 0; k < pos; k++){
printf("%i: %sn",k,string[k]);
free(string[k]);
}
}
}
我正在尝试编写一个程序,它将读取用户的一句话,然后将其分解为组成词,每个词都存储在自己的char数组中。
我使用malloc()来分配足够的内存来容纳每个单词,并在使用后释放它。
第一次运行很好,但在随后的循环中,短于5个字符的单词(并且只有在键入多个单词时,用空格分隔)将无法正确显示,并随机添加额外的字符/符号。
这可能是因为malloc使用了非空的空闲内存吗?如果是这种情况,我应该如何正确使用malloc?
我找到的唯一补救方法就是使用我注释掉的代码。它用\0填充新分配的char数组。
谢谢!
样本输出:
input words(0): we we we
0: we
1: we
2: we
input words(1): we we we
0: we�
1: we�
2: we
您有两个问题:
1) 您在以下条件下使用sizeof read
:
for(i = 0; i < sizeof read; i++){
如果输入行没有sizeof read
那么长怎么办?您应该在此处使用strlen(read)
。
2) 当您为字符串分配足够的内存时,并不是0终止它们。您可以calloc()
将分配的全部内存清零。由于您正在立即写入它们,所以我更喜欢使用malloc()
,而不是不必要地使用calloc()
清零,并在循环后立即使用终止字符串
for(j = 0; j < t; j++){
string[pos][j] = read[i-(t-j)];
}
string[pos][j] = 0; // 0 terminates the string.
附言:sizeof(char)
总是1。
您永远不应该假设malloc给您的内存为零。
所有(c样式)字符串都应该以值为0的尾随字符结尾,如果不这样做,则会得到未定义的行为。
在未定义行为的领域中,结果是未定义的!就像在编译器中一样,它可以自由地做它喜欢做的事情。
避免不明确的行为。