0

C で ToLower(char *str) の独自の実装を作成していますが、関数でセグメンテーション違反が発生しています。私が書いた機能は次のとおりです。

void ToLower(char *str)
{
    while(*str != '\0')
    {
        if(*str >=65 && *str<=90)
        {
            // It fails in the below assignment
            *str = *str + 32;
        }
        str++;
    }

}
4

4 に答える 4

11

次のように呼び出すと、ほぼ確実に失敗します。

int main(void)
{
    ToLower("HelloWorld");
    return 0;
}

これは、"HelloWorld"がリテラルの定数文字列であり、その内容を変更できないためです。

代わりに試してください:

int main(void)
{
    char str[] = "HelloWorld";

    // Now str is your own local buffer, that you can modify.
    // It is initialized with the text, but that text can be changed.
    ToLower(str);
    return 0;
}
于 2013-10-10T15:57:56.653 に答える
4

一般に、文字列を操作する関数で長さパラメーターを受け入れるのは適切な形式であると考えられています。このように、null で終了していない文字列を渡すと、関数は入力の末尾を超えてループしません。

デバッガーを使用して関数呼び出しをステップ実行するか、ループに print ステートメントを追加して、反復回数を確認できます。

于 2013-10-10T15:57:22.673 に答える
0

関数の名前はToLower()、ANSI C バージョンの , を書き直していることを示していますtolower()(つまり、1 つの文字を大文字から小文字に変更している) が、実際には文字列全体を変更する必要があることを実装が示しています。おそらく、名前StrToLower()はあなたが本当に意図しているものですか?(つまり、文字列全体を変更します)。その場合は、次のコードが示しています。(本当に を書き直したい場合はtolower()、C バージョンに似たプロトタイプを使用し、呼び出しごとに 1 つの文字のみを変更して、実際には別の質問にする必要があります)

この回答は、質問にタグ「c」があるため、.NETバージョンString.ToLower()(文字列を変換します)が必要ないことを前提としています。これが間違った仮定である場合は、私の暴言を無視してください。

このメソッドは、char *str="STRING";、または定数文字列 ( "STRING") を引数として使用します。
[拡張] OPが本当に望んでいた場合に備えて、ToLowerの実装を含めます。

#include <stdio.h>
char * StrToLower(char *str) ;
int toLower(int chr);

int main(void)
{
    char lowered[] = "UPPER to Lower"; 

    sprintf(lowered, "%s",StrToLower(lowered));
    printf("%s\n", lowered); //works with a variable buffer argument

    lowered[0]=0;//clear the buffer

    sprintf(lowered, "%s",StrToLower("UPPER to Lower")); 
    printf("%s\n", lowered); //also works with a literal string argument

    getchar();//view results
    return 0;
}

char * StrToLower(char *str)
{
    char *pNew1 = str;
    char *pNew2 = str;

    if(str != NULL) //NULL ?
    {
        if(strlen(str) != 0) //"" ?
        {
            while(*pNew1)
            {
                *pNew2 = toLower(*pNew1); 
                ++pNew2;
                ++pNew1;
            }
            *pNew2 = '\0';
            return str;// return changed string
        }              // and prevent returning null to caller
    }
    return "";//Will never get here for non-null input argurment
}   

int toLower(int chr)//touches only one character per call
{
    return (chr >='A' && chr<='Z') ? (chr + 32) : (chr);    
}

結果:(ローランドのコメントに答える)
ここに画像の説明を入力

于 2013-10-10T16:51:01.443 に答える
-2

安全な変数の場合、次のプロトタイプを使用できます。

void ToLower(const char *str)
于 2013-10-10T16:16:10.657 に答える