尝试'rewrite'字符数组时出错C++



我正在尝试使用以下代码将字符串转换为全部大写:

int client::get_upper(char*item_in)
{
    int k ;
    char * temp_str;
    int length = strlen(item_in);
    temp_str = new char [length+1];
    for(k = 0; k < length; ++k)
        temp_str[k] = toupper(item_in[k]);
    temp_str[k] = '';
    for(k = 0; k < length; ++k)
        item_in[k] = temp_str[k];
    return 0;
}

然而,当我尝试这样做时,我从Visual Studio收到访问冲突写入位置xxxxxx 这是针对一个类的,所以我被限制使用实际的字符串。

如果使用

得当,您的代码可以正常工作(最简单的方法是简单地传递一个本地字符串,如下所示):

char test[] = "stackoverflow.com";
client::get_upper(test); // client interpreted as a namespace

现在,您的函数充满了糟糕的方法,即未托管的冗余副本(内存泄漏)。

重写了一点:

int client::get_upper(char *item_in)
{
    unsigned int length = strlen(item_in);
    for(int i = 0; i < length; ++k)
        item_in[i] = toupper(item_in[i]);
    return 0;
}

如果你想尝试一下,这里有一些适合你的东西,只是为了好玩:

int client::get_upper(char *item_in)
{
    int length = strlen(item_in);
    for(int i = 0; i < length; ++i)
        if((item_in[i] >= 97 && item_in[i] <= 122))
            item_in[i] = (int)item_in[i] - 32; 
    return 0;
}

你的错误很可能来自这样一个事实,即你试图推动一个你可能没有真正考虑过的动态字符数组。只需使用本地字符串,一个简单的以 null 结尾的数组。你并没有真正付出那么多,所以这只是猜测工作。我所能做的就是帮助你简化你的表达。由于返回值不执行任何操作,请考虑将其应用于某些内容或切换到 void

希望对您有所帮助。

假设您正确调用了该代码,我认为您有一个 temp_str[k] = '\0' 的错误;

调用get_upper时,是否传递了字符串文字?例如,您的调用代码是否如下所示:

char *mystr = "stackoverflow.com";
client.get_upper(mystr)?

这很可能会在Visual Studio中触发访问冲突。

如果是这种情况,您可以将 mystr 的定义更改为:

char mystr[] = "stackoverflow.com";

如果不看到函数的调用方式,我们就无法知道为什么会出现错误。

我怀疑错误与调用上下文以及item_in实际指向的内容有关。

杰里米·弗里斯纳(Jeremy Friesner)的评论是恰到好处的 - 你有泄漏,如果目标是破坏性的,你无论如何都不需要中间缓冲区。

不允许

使用标准字符串类这一事实并不意味着您必须将其编写为整体函数。

我会编写一个简单的函数来就地进行转换。然后,如果需要支持处理只读字符串,请编写另一个复制输入的函数(使用第三个函数),然后对副本执行就地转换。

char *duplicate(char const *input);
char *upper_str(char *input); // does in-place transformation
char *upper_str(char const *input); // duplicates, then transforms the duplicate

相关内容

  • 没有找到相关文章

最新更新