我正在尝试使用以下代码将字符串转换为全部大写:
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