- 締切済み
C言語で分からないところがあるのですが
すみません。C言語のポインタで分からないことがあって来ました。 ポインタの理屈は理解してはいるのですが、いざソースコードを書いてみようということになると全く手がつけられずにいます。 以下のソースコードですが、strlen()と同じ働きをする関数mystrlen()と、strcmp()と同じ働きをする関数mystrcmpを、ポインタを使って作成するものです。どこをどうすればいいのか教えてくださいませんか。 #include <stdio.h> int main(void) { char str1[80], str2[80]; int i, j; int len1, len2; printf("第1の文字列を入力してください: "); gets(str1); printf("第2の文字列を入力してください: "); gets(str2); /* * 文字列の長さを確認する */ /* NULL文字(文字列の最後)まで読み飛ばす */ for (len1 = 0; len1 < 80 && str1[len1] != '\0'; len1++) ; /* ループ終了後、len1 に文字列の長さが入っている */ if (len1 < 80) { printf("%s は %d 文字の長さです\n", str1, len1); } else { printf ("第1の文字列が80字以上あります\n"); } /* str2 についても同様 */ for (len2 = 0; len2 < 80 && str2[len2] != '\0'; len2++) ; if (len2 < 80) { printf("%s は %d 文字の長さです\n", str2, len2); } else { printf ("第2の文字列が80字以上あります\n"); } if (len1 < 80 && len2 < 80) { for (i = 0; i < 80 && str1[i] != '\0' && str2[i] != '\0' && str1[i] == str2[i]; i++) ; if (str1[i] == str2[i]) { /* 両者同時に == '\0' のはず*/ printf("文字列は等しい\n"); } else if (str1[i] < str2[i]) { /* str1[i] == '\0' のはず*/ printf("%s は %s より小さい\n", str1, str2); } else { /* str2[i] == '\0' のはず*/ printf("%s は %s より大きい\n", str1, str2); } } /* * 十分なスペースがあれば、str2をstr1の最後に連結する */ if (len1 + len2 < 80) { /* str1 の末尾を探す */ for (i = 0; str1[i] != '\0'; i++) ; /* ループを抜けた段階では i は len1 と同じはずなので、 上記のループを作らず、i の代わりに len1 を用いるのも可 */ /* それ以降に str2 の中身をコピーする */ for (j = 0; str2[j] != '\0'; j++) { str1[i+j] = str2[j]; } str1[i+j] = '\0'; printf("%s\n", str1); } else { printf ("文字列をつなげた長さが80字以上あります\n"); } /* * str2をstr1にコピーする */ if (len1 + len2 < 80) { for (i = 0; str1[i] != '\0'; i++) { str1[i] = str2[i]; } str1[i] = '\0'; printf("%s %s\n", str1, str2); } return 0; }
- みんなの回答 (7)
- 専門家の回答
みんなの回答
> #3 確かに、質問者さんにとっては、ゴミ回答だったかもしれませんね。 ただ、以下の例ではポインタを配列っぽく見せかけているに過ぎないということだけは、(今は理解出来ないかもしれないけど、)気には止めておいてください。 配列のつもりで sizeof とかしないように! int mystrlen(char str[]) /* 仮引数中の配列宣言は、ポインタの宣言とみなされます */ { int i; for (i=0 ; str[i] ; i++) { /* str[i] は *(str + i) と等価です */ } return i; } 念のため付け加えておきますが、配列とポインタは本来別物です。 # ごめんやっぱりゴミ回答かも。
- yama5140
- ベストアンサー率54% (136/250)
>どこをどうすればいいのか教えてくださいませんか。 ・関数化する ・関数は、ポインタを使った処理とする 質問の主旨は、上の2件ですよね。 ソースは、#3 さんのご指摘のとおり、全て文字配列での処理です。 まず、そのまま配列を使って関数化する。 次に、これを、ポインタを使った関数とする。 の方針でやれば簡単かと思います。 ++++++++++++++++++++++++++++++++++++ 関数化は、「同じような処理を1回の記述ですますこと」と考えればよいかと。 言い換えれば、ソースには、/* str2 についても同様 */ というコメントがありますが、「同様」部分を一つにまとめる、ということです。 for (len1 = 0; len1 < 80 && str1[len1] != '\0'; len1++); と for (len2 = 0; len2 < 80 && str2[len2] != '\0'; len2++); は、 len1 = mystrlen( str1 ); len2 = mystrlen( str2 ); とした方がクールですよね。 ↑これが関数を呼び出す方です。 関数の方は、文字列の長さ(整数)を返すので関数の「型」は、int です。 関数の「名前」は、mystrlen だから int mystrlen( char str[] ) { int len; for( len = 0; len < 80 && str[len] != '\0'; len++ ); // 一つにまとまった! return( len ); } 簡単でしょ、ここまでしてから「ポインタ」について質問しても遅くなかったかと。 蛇足 main 関数より下方にコーディングする場合は、・・・まっ、やってみれば判るか。 なお、ウォーニングは完璧に無くす癖をつけると、後々楽です。 ++++++++++++++++++++++++++++++++++++ ポインターを使った関数化については、 http://www.bohyoh.com/CandCPP/C/Library/index.html に「回答」が載っています。 必要なのは、 文字列長取得 strlen 文字列比較 strcmp 連結コピー strcat 上書コピー strcpy ですよね。それぞれのページの■実装例■をパクルだけです。 なお、strcmp() については、■実装例■が、strncmp() のと入れ違っているので注意してください。 ただ、★何も考えずにパクルのではなく、どうしてこんな記述?、と考えながらパクればと思います。
- D-Matsu
- ベストアンサー率45% (1080/2394)
「理解している」けど「全く手が付けられない」というのは、要するに「理解した気になっているだけ」という事ではあります。 使い方のサンプルと一緒に教わるのが普通ですから、本当に理解しているなら何かしらのとっかかりはあるはず。 それ以前の問題として「関数」は理解できていますか? また、質問で提示したmain内のどこを関数にすればよいかは理解できていますか?
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
#3 です。 チェックしてませんでした m(_ _)m while(*a && *b && *a++==*b++); 訂正↓ while(*a && *b && *a==*b) a++,b++;
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
>int mystrlen(char str[]) >{ > int i; > for (i=0 ; str[i] ; i++) { > } > return i; >} > >str は char の配列のように見えますが、実際には char へのポインタです。 http://okwave.jp/qa/q6313314.html しっかり、ゴミ回答の文字配列をポインターだと思い込んでおられるようですね。 あなたが行っているのは文字配列です。ポインターではありません。 一例として↓にポインターを使った mystrcmp() をあげておきますから、あなたとのプログラミングのし方/考え方の違いを勉強してください。 #include <stdio.h> //プロトタイプ宣言 int mystrcmp(char *, char *); int main(void) { char str1[80],str2[80]; char *judge[]={"<","==",">"}; printf("第1の文字列を入力してください: "); gets(str1); printf("第2の文字列を入力してください: "); gets(str2); printf("result: \"%s\" %s \"%s\"\n", str1, judge[mystrcmp(str1,str2)+1], str2); return 0; } int mystrcmp(char *a, char *b) { int judge; while(*a && *b && *a++==*b++); if(*a>*b) judge=1; else if(*a<*b) judge=-1; else judge=0; return judge; }
- k_kota
- ベストアンサー率19% (434/2186)
一言で言っちゃうと、全部だめ。 要するに main{ 結果=関数1(文字列二つ); 結果=関数1(文字列二つ); } 関数1(){ 本体 } みたいに書かないと行けません。 ポインタも関数も理解できてないように見えます。 なので、勉強し直して、もう少し分かってから質問するか、 もうちょっと手前の内容を質問して下さい。 答を書くのは簡単ですけど、それは望んでないと判断しています。
- asuncion
- ベストアンサー率33% (2127/6289)
質問の趣旨は何ですか? >以下のソースコードですが、strlen()と同じ働きをする関数mystrlen()と、 >strcmp()と同じ働きをする関数mystrcmpを、ポインタを使って作成するものです。 現状、main関数で全部書いてて、my何とかっていう関数が作れてないので、 それらを作りたいってことですか?