用C语言编写一个函数:
我写了以下程序:
int main()
{
char* output;
char *input = "My name is Pranay Godha";
output = numChar(input);
printf("output : %s",output);
getch();
return 0;
}
char* numChar(char* str)
{
int len = strlen(str);
char* output = (char*)malloc(sizeof(char)*len);
char* out = output;
int count = 0;
while(*str != '\0')
{
if(*str != ' ' )
{
count++;
}
else
{
*output = count+'0';
output++;
*output = ' ';
output++;
count = 0;
}
str++;
}
*output = count+'0';
output++;
*output = '\0';
return out;
}
我只是想知道我为输出字符串分配了len
的内存量,我觉得这比我应该分配的更多,因此会浪费一些内存。你能告诉我我能做些什么来提高记忆效率吗?
答案 0 :(得分:6)
我看到很多小错误。如果我是你的导师,我会把你的解决方案评为“C-”。这里有一些关于如何将其变成“A +”的提示。
char* output = (char*)malloc(sizeof(char)*len);
上述两个主要问题。首先,你忘了“释放”你分配的内存。但这很容易被原谅。
实际真正的错误。如果你的字符串只有1个字符长(例如“x”),你只能分配一个字节。但是您可能需要将两个字节复制到字符串缓冲区中。一个'1'后跟一个空终止'\ 0'。最后一个字节被复制到无效的内存中。 :(
另一个错误:
*output = count+'0';
“count”大于9时会发生什么?如果“count”为10,那么* output将被赋予冒号,而不是“10”。
首先编写一个只计算字符串中单词数的函数。将此函数的结果分配给变量调用num_of_words。
由于您可能会有超过9个字符的单词,因此某些单词将有两个或更多个数字用于输出。而且你需要考虑每个数字之间的“空间”。并且不要忘记尾随的“空”字节。
如果你考虑一个1字节无符号整数在字符串表示中最多可以有3个字符('0'..'255')不包括空字符或负数的情况,那么sizeof(int )* 3是整数表示的最大字符串长度的合理估计(不包括空字符)。因此,您需要分配的内存量是:
num_of_words = countWords(str);
num_of_spaces = (num_of_words > 0) ? (num_of_words - 1) : 0;
output = malloc(num_of_spaces + sizeof(int)*3*num_of_words + 1); // +1 for null char
所以这是一个相当不错的内存分配估计,但它肯定会在所有场景中分配足够的内存。
我认为你的程序中还有其他一些错误。首先,如果每个单词之间有多个空格,例如
"my gosh"
我希望您的程序能够打印“2 4”。但是您的代码会打印其他内容。如果字符串中有前导或尾随空格,则可能存在其他错误。并且内存分配估计不考虑在这些情况下插入的额外垃圾字符。
更新:
鉴于你坚持并试图在下面的答案中找到更好的解决方案,我会给你一个提示。我编写了一个函数,用于打印字符串中所有单词的长度。它实际上并没有分配字符串。它只是打印它 - 好像有人在你的函数要返回的字符串上调用了“printf”。你的工作是推断这个函数的工作原理 - 然后修改它以返回一个新的字符串(包含所有单词的整数长度),而不是只打印它。我建议你修改这个函数中的主循环,以保持字数的运行总和。然后分配一个size =(word_count * 4 * sizeof(int)+ 1)的缓冲区。然后再次循环输入字符串,将每个单词的长度附加到您分配的缓冲区中。祝你好运。
void PrintLengthOfWordsInString(const char* str)
{
if ((str == NULL) || (*str == '\0'))
{
return;
}
while (*str)
{
int count = 0;
// consume leading white space
while ((*str) && (*str == ' '))
{
str++;
}
// count the number of consecutive non-space chars
while ((*str) && (*str != ' '))
{
count++;
str++;
}
if (count > 0)
{
printf("%d ", count);
}
}
printf("\n");
}
答案 1 :(得分:1)
只要句子中的单词都不超过9个字符,输出数组的长度只需要是句子中的单词数,乘以2(以考虑空格),加上额外的一个用于null终止符。
所以对于字符串
My name is Pranay Godha
...你只需要一个长度为11的数组。
如果任何单词是十个字符或更多,您需要通过确定所需数字的长度来计算您的数组需要多少额外char
。 (例如,长度为10个字符的单词显然需要两个char
来存储数字10
。)
真正的问题是,这一切都值得吗?除非你特别要求(作业?)使用输出数组中所需的最小空间,否则我会注意分配一个适当大的数组并在写入时执行一些边界检查。