1

Here's my code for a function that change the case of the character. For example"ABC" would be turn to "abc" and vice versa.

char *flipCase(const char *src){

char *output;
output = malloc(sizeof(src));
//Copy source to output
strcpy(output,src);
int i = 0;
//Check if the case is lower or upper
while(output[i] != '\0')
{
    //Check if it's alphabetic
    if (isalpha(output[i]))
    {
        //if it's upper case
        if (isupper(output[i]))
        {
            //Convert to lower case and increment i
            output[i]= tolower(output[i]);
            i++;
        }
        //if it's lower case
        if (islower(output[i]))
        {
            //Convert to upper and increment i
            output[i]=toupper(output[i]);
            i++;
        }

    }
    //Else, skip it
    else 
    {
        i++;
    }

}
return output;}

For most of the time, it seems to be fine to me. However when it is tested it with "Hello World, How are you?". I expected "hELLO wORLD, hOW ARE YOU?" but my program gives "hELLO wORLD, hOW ARE YOU1" Notice the "1" at the very end instead of "?". What's causing the problem? How can I fix it?

4

5 に答える 5

3

バッファの割り当てが正しくないため、バッファ オーバーフローが発生します。

output = malloc(sizeof(src));

sizeof(VLA に適用されない限り) 常に定数を返すため、文字列の長さは取得されません。あなたが欲しいのはですstrlen( src ) + 1

ループ因数分解に関する他の回答には抽象的なレベルのポイントがありますが、ループは正しくないようです。常に次の文字に移動し、同じ文字を 2 回チェックすることはなく、バッファーの末尾から外れることもありません (最初にバッファーが有効であると仮定します)。制御フローは少し奇妙です。

于 2013-11-07T00:36:58.590 に答える
0

このバグは、ループ変数の二重インクリメントによって引き起こされます。

output[i] が大文字で、output[i+1] が小文字であるとします。次に、ループの次の部分が実行され、i がインクリメントされます。

    if (isupper(output[i]))
    {
        //Convert to lower case and increment i
        output[i]= tolower(output[i]);
        i++;
    }

そして今、i はすでにインクリメントされており、「元の」i の値を持っているため、ループの次の部分も実行され、i が 2 倍インクリメントされます。

    if (islower(output[i]))
    {
        //Convert to upper and increment i
        output[i]=toupper(output[i]);
        i++;
    }

このようなバグは、インデックス変数またはイテレータ変数が使用可能な場合は常に「while」ループよりも「for」ループが一般的に好まれる主な理由の 1 つです。「while」ループは、ファイルやソケットの読み取りなど、ループ条件の制御がローカル コードの制御を超えている場合にのみ使用してください。それ以外の場合は、「for」ループを使用します。

于 2013-11-07T00:50:31.527 に答える
0

最も重要なことは、malloc サイズが間違っていたことです (あなたのものは常にポインターのサイズを malloc するでしょう) 第二に、ロジックが WRT の上下でめちゃくちゃになり、出力はとりわけ 2 つの後続の大文字を見逃すことになります。それほど重要ではありませんが、データをコピーして操作する必要はありません。

char *flipCase(const char *src){
char *output=malloc(strlen( src ) + 1);
int i;

for(i=0; *src; src++,i++){
    if (isupper(*src)){
        output[i]=tolower(*src);
    }else if (islower(*src)){
        output[i]=toupper(*src);
    }else{
        output[i]=*src;
    }
}
return output;
}
于 2013-11-07T01:16:59.090 に答える