2016-11-29 9 views
-4

文字列と別の文字列を比較しようとしていますが、一致する場合は「正しいです」というテキストを出力しますが、動作させることはできません。ここでCで文字列を比較する際の問題

コードです:あなたのコードで

int main() 
{ 
    char * password = "Torroc"; 
    char * userInput; 

    printf("Please enter your password: "); 
    scanf("%s", userInput); 

    if (strcmp(password, userInput) == 0) { 
     printf("That is correct!"); 
    } 
} 
+1

'char * userInput;' - > 'char userInput [16];' – BLUEPIXY

+1

'scanf'が未設定ポインタになっていますか?誰があなたにそれを提案しましたか? – John3136

答えて

2

、ユーザ入力ポインタを使用すると、scanf関数呼び出しを使用して合格しようとしている文字列を保持するための規定を持っていません。任意の文字列を保存/割り当てしようとする前に、スタック内のcstringのuserInputにスペースを割り当てる必要があります。だから... ...

は、次のコードを変更する必要があります。

char * userInput; 

に:ここで

char userInput[200]; 

、200だけで任意の値です。あなたの場合、最大値を選択してください。文字列の長さは(\ 0)の場合は+1です。

+0

私は説明しました! – Ehsan

+0

Opps!私の間違い、タイプミス。 – Ehsan

+0

'scanf("%199s "、userInput);'と 'scanf'の戻り値をチェックするために、潜在的なバッファオーバーフローを避けるために' scanf() 'にも制限を設けます。 – chqrlie

1

文字を入力するときは、文字をどこかに格納する必要があります。

char* userInput; 

は、初期化されていないポインタです。キーボードからの読み取り時

だからまず、あなたはそれが上書きされてしまうため、ユーザは\ 0 127 + 1よりも多くの文字を入力しないことを確認する必要があり

char userInput[128]; 

今、あなたの入力のための配列を宣言しますスタックのようにキーボードから読み取る最良の方法は、fgetsを使用することです。ユーザーが単にfgetsがNULLを返すものを書き込まずにENTERを押した場合は、戻り値を確認することもできます。

if (fgets(userInput, sizeof(userInput), stdin) != NULL) { 

これで、ユーザーが入力した文字列と行末の文字が追加されました。それを削除するには、あなたは今、あなたはあなたがCで「文字列」を考えるとき、あなたはchar年代の配列としてそれを見る必要がある文字列

if (strcmp(password, userInput) == 0) { 
     puts("That is correct!"); 
    } 
+0

'scanf("%s "、userInput)'は 'fgets()'とは異なるセマンティクスを持っていることに注意してください。 'scanf'は'%s'形式で、空白で区切られた単語を読み込みます。 'fgets'は行全体を読み込みます。 OPは彼が望むものを決める必要があります。 (通常、パスワードには空白を含めるべきですが、それはCの問題ではなく、アプリケーションの動作の問題です。) 'scanf("%20s "、userInput)'のようなものは、バッファオーバーランを避けることができます。 –

+0

@KeithThompson私はfgetsを使いやすくするために、より多くの解析パワーが必要な場合には常に結果にsscanfを使うことができます –

+0

改行をザッピングするための別のイディオムは 'userInput [strcspn(userInput、" \ n ")] = '\ 0' ; '。 –

0

を比較することができ

char* p = strchr(userInput,'\n'); 
    if (p != NULL) *p = '\0'; 

ような何かを行うことができます。

私は簡潔にするための識別子sの代わりuserInputを使用してみましょう:

 0 1 2 3 4 5   9 
    +---+---+---+---+---+---+-- --+---+ 
s -> | p | i | p | p | o | \0| ... | | 
    +---+---+---+---+---+---+-- --+---+ 

char s[10] = "pippo"; 

を作成しますものです。

つまり、図のように最初の6 バイトが初期化されたメモリブロックです。 s変数はありません。

代わりに、

char *s; 

ようchar *を宣言するcharへのポインタを保持できる変数を作成します。

+------------+ 
s| 0xCF024408 |  <-- represent an address 
    +------------+ 

あなたがこの方法を考える場合、あなたがやっていることをすぐに気づく:

scanf("%s",s); 

fiで意味がある文字列を保持するのに十分なメモリがある最初のケースです。

2番目のケースでは、変数sがランダムなアドレスを指していて、未知のメモリ領域に何かを書き込むことになります。

完全にするために、同様のケースで:

char *s = "pippo"; 

あなたは、メモリ内の次のような状況があります。

    0 1 2 3 4 5 
       +---+---+---+---+---+---+  Somewhere in the 
    0x0B320080 | p | i | p | p | o | \0| <-- readonly portion 
       +---+---+---+---+---+---+  of memory 


    +------------+  a variable pointing 
s| 0x0B320080 | <-- to the address where 
    +------------+  the string is 

あなたがどこか他sポインティングを行うことができますが、あなたはの内容を変更することはできません文字列はsです。