【问题标题】:tolower() and toupper() aren't working [closed]tolower() 和 toupper() 不起作用[关闭]
【发布时间】:2013-04-08 10:40:34
【问题描述】:

我的代码在这里:

char* kropecka(char* tab)
{
    int a=0,b=0;
    char* zwr;
    zwr=(char*)malloc(30*sizeof(char));

    for(a;strlen(tab);a++)
    {
        if(tab[a]!='.')
        {
            if(isupper(tab[a]))
                zwr[b]=tolower(tab[a]);
            if(islower(tab[a]))
                zwr[b]=toupper(tab[a]);
            b++;
        }
    }
    zwr[b]='\0';
    return zwr;
}

没有错误、警告或类似的东西。但是当我给他一些字符串时程序崩溃了:

--------------- Microsoft Visual C++ 调试库 --------------------------------------- 调试断言失败!

程序:...s\Visual Studio 2010\Projects\C_homework\Debug\C_homework.exe 文件: f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c 行:56

表达式:(无符号)(c + 1)

有关您的程序如何导致断言失败的信息, 请参阅有关断言的 Visual C++ 文档。

(按重试调试应用程序)

---------------中止重试忽略

编译器:Visual Studio 2010 包含的库:stdio.h、string.h、ctype.h、stdlib.h(用于 main() 中的 system() 函数)。

【问题讨论】:

  • 执行tolower() next if(islower) 匹配执行toupper(),使用else
  • 在您的“if (isupper()...; if (islower()...;”代码中,您似乎正在尝试切换大小写,但这总是会导致大写。您可以通过在第二个if 上添加else 将其转换为适当的切换。

标签: c string uppercase lowercase


【解决方案1】:

来自 C 标准:

标题<ctype.h> 声明了几个对字符分类和映射有用的函数。在所有情况下,参数都是一个 int,其值应表示为无符号字符或应等于宏 EOF 的值。如果参数有任何其他值,则 行为未定义

强调我的。

MSDN's description of toupper() hints at this as well:

为了让 toupper 给出预期的结果,__isascii 和 isupper 必须都返回非零值。

isascii():

如果 c 是 ASCII 字符(在 0x00 – 0x7F 范围内),__isascii 返回一个非零值。

【讨论】:

    【解决方案2】:

    您的循环的退出测试是错误的。 strlen(tab) 将始终返回 false 或 true(取决于 tab)。这意味着您继续写入zwr 超出其分配的长度。这样做的影响是不确定的,但它最终崩溃也就不足为奇了。

    您可以通过将循环更改为来解决此问题

    for(a;a<strlen(tab);a++)
    //    ^^
    

    另一个可能的错误原因是zwr 被硬编码为 30 个字节。对于tab 的所有可能值,这显然是不够的,因此您可以将代码更改为

    size_t len = strlen(zwr)+1;
    zwr=malloc(len);
    for(;a<len;a++)
    

    【讨论】:

    • @mah 我想我正在回答被问到的问题。我已经更新了我的答案以更清楚地解释这一点。如果您仍然不同意,请您解释一下为什么我的回答不恰当?
    • 我同意。缺乏解释使答案看起来是正交的,但这种解释更有帮助。
    【解决方案3】:

    这将永远运行:

    for(a;strlen(tab);a++)
    

    我想你的意思是:

    for(a;a < strlen(tab);a++)
    

    或者更好(因为strlen是O(n)):

    for(;tab[a];a++)
    

    【讨论】:

    • +1 表示每次迭代不使用 strlen
    • 哦,我没看到这个:/我的错。谢谢你。现在它正在工作。
    • 经过进一步思考,我已经删除了我的反对票 - 似乎正确终止他的 for 循环可以解决这个问题。
    【解决方案4】:

    检查调用堆栈 - 希望它能带您找到问题的根源。

    int __cdecl _chvalidator(
        int c,
        int mask
        )
     {
        _ASSERTE((unsigned)(c + 1) <= 256);
        return ( _pctype[c] & mask);
     }
    

    这个方法看起来像一个检查字符值边界的方法...

    isctype.c -

    /***
    * __chvalidator
    *
    * Purpose:
    *      This function is called by character testing functions in debug
    *      versions. This function test for validation of c as character.
    *      For improvement in performance, it is not used in non-debug
    *      version.  It is available in the static single-thread non-debug
    *      build, though, just in case C code that includes ctype.h is compiled
    *      /D_DEBUG /ML.
    *
    *******************************************************************************/
    

    简单来说,您似乎溢出了一个变量,即 Unsigned Char 可以取最大值 255。如果您将 1 添加到现有值 255 - 您会溢出。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      相关资源
      最近更新 更多