我正在尝试实现一个接收c字符串作为输入的函数,将所有小写字符转换为大写,然后将结果存储在输出参数中。以下是此功能的代码:
void makeUpper( const unsigned char* input, unsigned char* output )
{
int inputLength = strlen((char*)input);
int outputLength = strlen((char*)output);
for (int i = 0; i < inputLength; i++)
{
if ((input[i] >= 97) && (input[i] <= 122))
{
output[i] = input[i] - 32;
}
else
{
output[i] = input[i];
}
}
}
现在,在inputLength&gt;的情况下,会出现问题。 outputLength。为了解决这个问题,我在inputLength&amp;之间插入了以下代码。 outputLength声明和for循环。
if (inputLength > outputLength)
{
for (int i = 0; i < (inputLength - outputLength); i++)
{
strcat((char*)output, " ");
}
}
这不仅会产生错误(这个函数或变量可能不安全......),但我几乎可以肯定我会以错误的方式解决这个问题。但是,我想不出任何替代方案。
编辑:
我使用的主要功能如下:
int main()
{
unsigned char in[] = "HELLO aaaaaaaaaa 678";
unsigned char out[] = " xxxxxxxxx";
makeUpper( in, out );
cout << in << " -> " << out << endl;
makeUpper( out, in );
cout << out << " -> " << in << endl;
return 0;
}
我应该打印的功能是:
HELLO aaaaaaaaaa 678 -> HELLO AAAAAAAAAA 678xxxxxxxxx
HELLO AAAAAAAAAA 678xxxxxxxxx -> HELLO AAAAAAAAAA 678XXXXXXXXX
答案 0 :(得分:2)
您将“输出参数的当前内容”与“可用空间”混淆。前者是无关紧要的,关于后者的唯一信息是“至少有这么多可用的空间”。
现在它将取决于output
的空间首先如何分配。如果您做了类似
char output[100];
strcpy(output, "hello");
最终会有100个字符的空格,但实际上只使用了6个(5 + 1)。因此,您可以使用字符串“ThiS is a STRING”并使用您的函数处理它,没有问题。
但这不安全,因为你不知道有多少空间。以下方法会更好:
char *output;
output = malloc(100);
现在将您的函数原型更改为
void makeUpper( const unsigned char* input, unsigned char** output )
在您的功能中,您可以
inputLength = strlen(input);
*output = realloc(*output, inputLength + 1);
这将确保为输出分配足够的空间。或者你可以在输入向量中返回值 - 你已经知道那里有足够的空间......
编辑在您提供的示例中,output
中有足够的空间;这个问题只是将(大写)输入“安全地复制”到输出中。在这种情况下,您的函数可能如下所示:
void makeUpper( const unsigned char* input, unsigned char* output )
{
int inputLength = strlen(input);
int outputLength = strlen(output);
int ii;
for (ii = 0; ii < inputLength; ii++)
{
output[ii] = toupper(input[ii]);
}
if(outputLength < inputLength) output[ii] = '\0';
}
最后一行是为了确保如果你增加output
的长度(再次假设这是你可以有效访问的内存),那么你仍然需要确保终止{{1}字符串末尾的字符。在您的示例中,当nul
比input
短时,您希望“输出字符串的其余部分”仍然存在,因此您需要output
条件。
一般情况下 - 如果您不确定if
是否足够大,则无法在不访问指针地址的情况下使其变大 - 有时称为“句柄”。
答案 1 :(得分:0)
如果可以假定在函数中创建输出缓冲区:
// C++ version
void makeUpper(const unsigned char* input, unsigned char*& output)
{
// assume output = null
int inputLength = strlen((const char*)input);
output = new unsigned char[inputLength + 1];
memset(output, 0, inputLength + 1); // initialize the array to 0's
for (int i = 0; i < inputLength; i++)
{
output[i] = ::toupper(input[i]); // why reinvent the wheel
}
}
// C version
void makeUpper(const unsigned char* input, unsigned char** output)
{
// assume output = null
int inputLength = strlen((const char*)input);
*output = (unsigned char*)malloc((inputLength + 1) * sizeof(unsigned char));
memset(*output, 0, (inputLength + 1) * sizeof(unsigned char)); // initialize the array to 0's
for (int i = 0; i < inputLength; i++)
{
(*output)[i] = ::toupper(input[i]);
}
}
output
需要被控制它的人删除/释放。
如果您不想在函数内正确调整output
的大小:
void makeUpper(const unsigned char* input, unsigned char* output, unsigned int output_size)
{
// assume output != null, the current contents of output are irrelevant - you need it's size
int inputLength = strlen((const char*)input);
int maxLength = (inputLength < output_size - 1 ? inputLength : output_size - 1);
memset(output, 0, output_size); // clear output
for (int i = 0; i < maxLength; i++)
{
output[i] = ::toupper(input[i]); // why reinvent the wheel
}
}
注意:在我写答案时删除了C ++标记。这实际上只影响第一个解决方案(正如您使用malloc
而不是new
)。除非你的要求绝对需要,否则我会回避realloc
或calloc
。