質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1597閲覧

C言語 文字列の操作の問題

aya0

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/02/28 08:49

編集2020/03/02 00:01

問題
文字列の配列を読み込む関数を作成する。
"$$$$$"を読み込んだ時点で読み込みを中断・終了する。
"$$$$$"より前に入力された全文字列を表示する。

下記は私が考えた、この問題に対するプログラムです。

c

1#define _CRT_SECURE_NO_WARNINGS 2#define N 128 3#define A 128 4#include <stdio.h> 5#include <string.h> 6#include <ctype.h> 7 8 9void put_strary2(const char s[][A], int n) 10{ 11 int i, j, l, m; 12 /*-入力-*/ 13 for (i = 0; i < n; i++) { 14 15 int j = 0; 16 int k = 0; 17 18 while (s[i][j]) { 19 do { 20 scanf("%c", &s[i][j]); 21 if (s[i][j] == '$') { 22 k++; 23 } 24 else 25 break; 26 j++; 27 } while (k < 5); 28 } 29 30 if (k == 5) 31 break; 32 33 } 34 /*-出力-*/ 35 printf("%d", i); 36 /*上の行はiに代入されてる値を調べるために追加しました。なぜi=0となってるのか分からないです*/ 37 for (l = 0; l < i; l++) { 38 for (m = 0; s[l][m] != '\0'; m++) { 39 printf("%c", s[l][m]); 40 } 41 printf("\n"); 42 } 43} 44 45 46int main(void) 47{ 48 char cs[N][A] = { "0" }; 49 printf("文字列を入力\n"); 50 put_strary2(cs, N); 51 52}

"$$$$$"を読み込んだ時点で読み込みを中断・終了するところまでは、実行できたのですが、"$$$$$"より前に入力された全文字列を表示することができませんでした。
そこで試しに、入力が終了したところでiの値を確認したところ0となっていました。
なぜi=0になってしまうのか理由が知りたいです。
宜しくお願いします。

下記は解決後のプログラムです。

c

1#define _CRT_SECURE_NO_WARNINGS 2#define N 128 3#define A 128 4#include <stdio.h> 5#include <string.h> 6#include <ctype.h> 7 8 9void put_strary2(char s[][A], int n) 10{ 11 int i, j, l, m; 12 /*-入力-*/ 13 for (i = 0; i < n; i++) { 14 15 int j = 0; 16 int k = 0; 17 18 scanf("%s", s[i]); 19 20 while (k < 5) { 21 if (s[i][j] == '$') { 22 k++; 23 j++; 24 } 25 else 26 break; 27 } 28 29 if (k == 5) 30 break; 31 32 } 33 /*-出力-*/ 34 printf("%d\n", i); 35 /*上の行はiに代入されてる値を調べるために追加しました。*/ 36 for (l = 0; l < i; l++) { 37 for (m = 0; s[l][m] != '\0'; m++) { 38 printf("%c", s[l][m]); 39 } 40 putchar('\n'); 41 } 42} 43 44 45int main(void) 46{ 47 char cs[N][A] = { "0" }; 48 printf("文字列を入力\n"); 49 put_strary2(cs, N); 50 51}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2020/02/28 09:28

char cs[][A] = { "0" };は char cs[N][A] = { "0" };と違いますか?
aya0

2020/02/28 22:54

ご指摘ありがとうございます! 修正しました。
guest

回答3

0

#define _CRT_SECURE_NO_WARNINGS があることから
コンパイラは Visual C++ を使っているんだと思いますが、
コンパイル時に警告メッセージが出ませんか?

put_strary2 の引数 s は const char の配列(へのポインタ) です。
const char は書き換え不可能な char という型です。
なのに scanf("%s", s[i]); で配列の中の文字を書き換えていて、その警告が出るはずです。
const を付けてはいけません。

また、$ が 5個以上あるかどうかは strncmp を使えば簡単に分かります。

C

1#define _CRT_SECURE_NO_WARNINGS 2#define N 128 3#define A 128 4#include <stdio.h> // scanf, puts, printf 5#include <string.h> // strncmp 6 7void put_strary2(char s[][A], int n) 8{ 9 int i, j; 10 for (i = 0; i < n; i++) { 11 scanf("%s", s[i]); 12 if (strncmp(s[i], "$$$$$", 5) == 0) break; 13 } 14 printf("%d\n", i); 15 for (j = 0; j < i; j++) 16 puts(s[j]); 17} 18 19int main(void) 20{ 21 char cs[N][A]; 22 puts("文字列を入力"); 23 put_strary2(cs, N); 24}

投稿2020/02/29 16:21

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aya0

2020/03/02 00:05

ご指摘ありがとうございます! const使うと書き換えできないのに使ってしまっていたことに気づけて良かったです! strncmp使うとコードがすっきりしていいですね! 参考にします!
guest

0

ベストアンサー

ここの部分が無限ループになっていて k = 5 にならないと抜けれない状態です。

c

1while (s[i][j]) { 2 do { 3 scanf("%c", &s[i][j]); 4 if (s[i][j] == '$') { 5 k++; 6 } 7 else 8 break; 9 j++; 10 } while (k < 5); 11 }

でこの二つのループを抜けると k のチェックが待っていて確定で for loop も抜けるので i はインクリメントされないので 0 のままです。

c

1if (k == 5) 2 break;

また j のインクリメントもされないので s[0][0] に無限に代入を続けている形です。最後の出力される s は一番最後に保存した1行のみです。自分はc言語はあまり分からないので何とも言えませんがconst char に文字列を入れるのはありなのでしょうか?

何かの助けになれば幸いです。

投稿2020/02/29 00:39

mipopon

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aya0

2020/02/29 03:55 編集

回答ありがとうございます! mipoponさんのおかげで、for文の中のwhile文でk>5にならない限り、無限にループしてしまってiが増えてないことに気づけました! プログラムも修正して正常に動きました! すごく助かります!
guest

0

for (i = 0; i < n; i++)の中にあるwhileのループを抜けるときにkは5になります。抜けたところでif(k==5)でforを抜けるのでiは0です。

投稿2020/02/28 09:35

tatamyiwathy

総合スコア1039

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aya0

2020/02/28 23:02

回答ありがとうございます。 for文を抜けた後、iの値が0になるのか別のコードで試したのですが、以下のコードの場合、i = 4になりました。 なぜ、for文を抜けた後、i=(初期値)になる場合とi=(最終値)になる場合があるのか知りたいです。 宜しくお願いします。 ``` int main(void) { int i, j; j = 0; for (i = 0; i < 10; i++) { if (j == 4) break; else j++; } printf("%d",i); } ```
mipopon

2020/02/29 00:43

常にi=(最終値)になります。ただ @aya0 さんのコードだと for loop が1周しかしないので i = 0 と言う事です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問