2016-12-13 3 views
0

はコードです:私のstrcatコードでprintfの何が問題になっていますか?ここでは...</p> <p>を、私はこのプログラムはstrcatの機能をエミュレートするために作られてきたが、私は理解していないのprintfとの誤差がある

#include <stdio.h> 

char *mystrcat(char *s1, char *s2); 

int main(void) 
{ 
    char *s1,*s2; 
    s1="asdad"; 
    s2="asdad"; 
    s1=mystrcat(s1,s2); 
    printf(s1); 

    return 0; 
} 
char *mystrcat(char *s1,char *s2) 
{ 
    int i,j; 
    for(i=0;s1[i]<'\0';i++) ; 
    for(j=0;s2[j]!='\0';j++) s1[i+j]=s2[j]; 
    s1[i+j]='\0'; 
    return s1; 
} 
+3

2)連結文字列を格納するスペースが 's1'にありません。 – BLUEPIXY

+1

さらに、 'printf(s1)'ではなく 'puts(s1)'や 'printf("%s \ n "、s1)'を使うべきです。特に、文字列がコンパイル時定数でない場合、 'printf'の書式文字列として使用することは、書式指示子を含む場合には重大な問題です。 – Arkku

答えて

4

最初の問題は、s1s2を追加するのに十分な領域がないことです。 s1で指されるバッファーのサイズは、少なくともstrlen(s1) + strlen(s2) + 1(NULターミネーターである+ 1)にする必要があります。

第2の問題は、文字列リテラルが読み取り専用であることです。 s1"asdad"に割り当てると、(潜在的に)読み取り専用メモリへのポインタが作成されます。もちろん最初の問題は、書き込み可能であっても最後に追加するための十分なスペースがないことを意味しますが、これはCの一般的な落とし穴の1つであり、言及する価値があります。 (すでにanother answerで述べた)

第3の問題は、比較s1[i] < '\0'が間違っていると、ループが1つでも反復処理を実行されませんので、あなたが正しくs1の長さを見つけることができませんということです。正しい条件は、2番目のループの場合と同じです。!= '\0'です。 (これは最初からs1を誤って上書きしてしまったので、問題1をマスクします。)

+0

"size of' s1' "に注意してください。 's1'は' char * 'なので、そのサイズはそれが指しているオブジェクトとは無関係です。 – EOF

+0

@EOF Trueを修正しました。 – Arkku

+0

ありがとう! 2番目の問題を解決するにはどうすればよいでしょうか? – Metalingus

4

少なくとも、s1[i] < '\0'は同じですs1[i] < 0として、常にfalseです。

+1

'char'は' s2 [i] <0'を真にする 'signed'とすることができますか? –

+1

FiddlingBitsは非常に良い点です:関係式が間違っていますが、指定した理由ではありません。たとえば、 '(int)(char)( - 1)'は私のプラットフォームで-1を返し、 '(int)(unsigned char)( - 1)'のように255になりません。同様に、 '(int)(signed char)( - 1)'が-1になる間に、別のプラットフォームでは前者の場合255(または別の値、すべての実装で2の補数を使用するわけではありません)という結果になります。コンパイラの中には、コンパイラフラグを介して 'char'を符号付きまたは符号なしにすることをサポートするものもあります。 'char'の署名度は、ISO C標準によって実装定義されたままなので、' s1 [i] <0'は常にfalseではありません。 –

関連する問題

 関連する問題