0

我正在尝试实现一个接收ac字符串作为输入的函数,将所有小写字符转换为大写,然后将结果存储在输出参数中。下面是这个函数的代码:

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 > outputLength 的情况下显然会出现问题。为了解决这个问题,我在 inputLength & 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
4

2 回答 2

2

您将“输出参数的当前内容”与“可用空间”混淆了。前者无关紧要,关于后者的唯一信息是“至少有这么多可用空间”。

现在它将取决于output首先如何分配空间。如果你做了类似的事情

char output[100];
strcpy(output, "hello");

您最终会得到 100 个字符的空间,但实际使用的只有 6 (5+1) 个。因此,您可以使用字符串“这是一个字符串”并使用您的函数处理它,没有问题。

但这并不安全,因为你不知道有多少空间。以下方法会更好:

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(再次假设这是你可以有效访问的内存),那么你仍然需要确保nul在字符串的末尾有一个终止字符。input在您的示例中,当短于时,您希望“输出字符串的其余部分”仍然存在output,因此您需要if条件。

一般来说——如果你不确定它output是否足够大,那么在没有访问指针地址的情况下就无法让它更大——有时称为“句柄”。

于 2013-10-29T21:12:18.557 回答
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)。我会回避realloccalloc除非您的要求绝对需要它们。

于 2013-10-29T21:15:40.150 回答