tolower() and toupper() aren't working [closed]

旧巷老猫 提交于 2019-12-13 09:45:17

问题


My code is here:

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;
}

There is no errors, warnings or something like this. But program crashed when I give him some string:

--------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed!

Program: ...s\Visual Studio 2010\Projects\C_homework\Debug\C_homework.exe File: f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c Line: 56

Expression: (unsigned)(c + 1) <= 256

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

--------------------------- Abort Retry Ignore

Compilator: Visual Studio 2010 Included libary: stdio.h, string.h, ctype.h, stdlib.h (for system() function in main() ).


回答1:


This will run forever:

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

I think you meant:

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

Or better (because strlen is O(n)):

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



回答2:


From the C standard:

The header <ctype.h> declares several functions useful for classifying and mapping characters. In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

Emphasis mine.

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

In order for toupper to give the expected results, __isascii and isupper must both return nonzero.

isascii():

__isascii returns a nonzero value if c is an ASCII character (in the range 0x00 – 0x7F).




回答3:


The exit test for your loop is wrong. strlen(tab) will always return either false or true (depending on tab). This means that you continue writing to zwr beyond its allocated length. The effects of this are undefined but its not surprising that it eventually crashes.

You can fix this by changing the loop to

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

Another possible cause of error is that zwr is hard-coded as 30 bytes. This clearly isn't sufficient for all possible values of tab so you could change the code to

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



回答4:


Check the callstack - hopefully it will take you to the root of the problem.

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

This method looks like one that checks for character value bounds...

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.
*
*******************************************************************************/

In simple terms it seems that you are overflowing on a variable i.e. Unsigned Char can take a maximum value of 255. If you add 1 to an existing value of 255 - you overflow on it.

Hope it helps.



来源:https://stackoverflow.com/questions/15877048/tolower-and-toupper-arent-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!