【问题标题】:error convert character in string to uppercase将字符串中的字符转换为大写时出错
【发布时间】:2015-03-17 02:02:48
【问题描述】:

我正在尝试将字符串的字符转换为大写字母

int main (void)
{
    int i = 0;
    int n = 0;
    static char *str[] = { "wow",
                           "RACEcar", 
                           "No devil lived on.",
                           "rotor" };

    for(i = 0; i < strlen(*str); i++)
    {
        if(str[i] != NULL)
        {
            n = function(str[i]);
        }
    }
    return 0;
}

int function(char* x)
{
   int i = 0;
   int j = strlen(x);
   char c;
   for(i = 0; i < j; i++)
   {
      c = toupper(x[i]);
      x[i] = c;
   }

   return 0;
}

我在x[i] = c; 所在的行出现错误提示exc bad access, code 2 我不确定为什么会出现此错误,是否需要创建另一个字符串并将 c 分配给新字符串? toupper 返回字符的大写版本,但实际上并没有更改元素本身,所以我不确定将 toupper 返回的值分配回元素有什么问题。

【问题讨论】:

  • 你是怎么调用那个函数的?你有没有机会做类似function("string"); 的事情?
  • 这与您的问题无关,但strlen 相对昂贵。 C 字符串不存储它们的长度;为了计算x 的长度,strlen 需要扫描整个字符串,对字符进行计数,直到达到 NUL。您的for 循环强制每个角色 发生这种情况;这是很多扫描。
  • 更改为static const char *str[] = { "wow", ... 现在看看为什么它不起作用。您正在尝试更改常量数据。
  • 这个循环:for(i = 0; i &lt; strlen(*str); i++) 的执行频率与字符串数组中第一个单词中的字母数相同。 "wow" 的字母比数组中的字符串少,因此永远不会使用最后一个值。如果“哇”更长,您可能会尝试大写随机内存。
  • 请注意,for 循环只会尝试转换 3 个字符串。正如所写,它在第一次崩溃。你真的需要for (i = 0; i &lt; sizeof(str)/sizeof(str[0]); i++) 的一些变体来转换所有的字符串。而且你确实需要定义可修改的字符串,比如:char str[][20] = { "...", ... };`.

标签: c string exc-bad-access toupper


【解决方案1】:

您的代码尝试修改字符串文字,这会导致未定义的行为。

字符串"No devil lived on."不可修改的。为了帮助编译器捕获错误,您应该将数组声明为:

static char const *str[] = { "wow", // etc.

由于历史原因,如果您忘记包含const,编译器必须让它通过而不破坏编译。但这仍然是一个错误,一些编译器无论如何都会发出警告。

对于 gcc,您可以使用标志 -Wwrite-strings 禁用对历史案例的支持;这将导致按原样为您的代码生成错误消息。

【讨论】:

    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    相关资源
    最近更新 更多