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

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

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

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

Q&A

解決済

5回答

1631閲覧

C言語のarrayを2つの部分に分けて考えたい

Miu-ktym

総合スコア1

C

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

0グッド

0クリップ

投稿2021/10/08 10:35

前提・実現したいこと

C言語の勉強を始めたのですが、この問題で詰まってしまいました。
6桁の数字を受け取って、年と月を打ち込むと、元号で表した年と季節(春:35月, 夏: 68月、秋: 911月、冬:122月)を表示するプログラムを作りなさい。昭和以前の元号には対応しなくても良い。
例、201812→平成30年冬、201903→平成31年春
201908→令和元年夏、202110→令和3年秋

プログラミング初心者なので、ifの中にarray[6]の配列を前の4つは年号の判定に使う、後ろの2つは季節の判定に使うということをしたのですが、うまくいきません。

発生している問題・エラーメッセージ

結果が、








となってしまいます。

### 該当のソースコード #include <stdio.h> void main() { int a[6]={}; printf("6桁の数字を入力して下さい。 "); scanf("%d",&a); if(a[0,1,2,3] >= 1927 && a[0,1,2,3] <=1989 && 03 <= a[4,5] && a[4,5]<= 05) //昭和が西暦何年から何年までかを指定。元年の次の年から printf("昭和%d年。春\n",64-(1989-a[0,1,2,3])); if(a[0,1,2,3] >= 1927 && a[0,1,2,3] <=1989 && 06 <= a[4,5] && a[4,5]<= 8) printf("昭和%d年。夏\n",64-(1989-a[0,1,2,3])); if(a[0,1,2,3] >= 1927 && a[0,1,2,3] <=1989 && 9 <= a[4,5] && a[4,5]<= 11) printf("昭和%d年。秋\n",64-(1989-a[0,1,2,3])); if(a[0,1,2,3] >= 1927 && a[0,1,2,3] <=1989 && 12 <= a[4,5] && a[4,5]<= 02) printf("昭和%d年。冬\n",64-(1989-a[0,1,2,3])); else if(a[0,1,2,3] == 1926 && 03 <= a[4,5]<= 05) //年号の始まりは元年と表示 printf("昭和元年です。春|n"); else if(a[0,1,2,3] == 1926 && 06 <= a[4,5]<= 8) //年号の始まりは元年と表示 printf("昭和元年です。夏|n"); else if(a[0,1,2,3] == 1926 && 9 <= a[4,5]<= 11) //年号の始まりは元年と表示 printf("昭和元年です。秋|n"); else if(a[0,1,2,3] == 1926 && 12 <= a[4,5]<= 02) //年号の始まりは元年と表示 printf("昭和元年です。冬|n"); if(a[0,1,2,3] >= 1990 && a <=2010) //平成が西暦何年から何年までかを指定。元年の次の年から printf("平成%d年です。",22-(2010-a[0,1,2,3])); if (03 <= a[4,5]<= 05) printf("春\n"); if (06 <= a[4,5] <= 8) printf("夏\n"); if (9 <= a[4,5] <= 11) printf("秋\n"); if ( 12 <= a[4,5] <= 02) printf("冬\n"); else if(a == 1989) //年号の始まりは元年と表示 printf("平成元年です。"); if (03 <= a[4,5]<= 05) printf("春\n"); if (06 <= a[4,5] <= 8) printf("夏\n"); if (9 <= a[4,5] <= 11) printf("秋\n"); if ( 12 <= a[4,5] <= 02) printf("冬\n"); } ```ここに言語名を入力 C言語 ### 試したこと 上記のもの以外にも、試したのですが、うまくいきません。おそらく、arrayの考え方が間違っているのだと思い、質問させていただきました。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

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

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

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

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

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

dodox86

2021/10/08 19:26

全く基礎ができていないと自覚されている質問者さんにこの問題はまだ難し過ぎます。なぜもっと簡単なことからやらないのでしょう。例えばまず入力した6桁の数字を年と月の部分に分解するだけ、とか。
fana

2021/10/09 01:44

> 昭和以前の元号には対応しなくても良い っていう場合,昭和は扱わなくてよいんじゃないかな?
guest

回答5

0

ベストアンサー

まずC言語の文法からやりましょう。話になりません。足し算すらわからない人に微積分なんて無理です。

次に、「動けばいい」という発想は捨てよう

次に、「コードを読もう」。ですね。

コードを読むコツは『一行レベルで、その行が何をしているかを考えながら読む』です。

質問者さんのロジックを読むと、

1. ユーザ入力によって a を受け取る(= 配列 a にセット) 2. 昭和n年の春かどうか 3. 昭和n年の夏かどうか 4. 昭和n年の秋かどうか 5 昭和n年の冬かどうか 2. 昭和元年の春かどうか 3. 昭和元年の夏かどうか 4. 昭和元年の秋かどうか 5 昭和元年の冬かどうか ...

となっています。

まあこのロジックでもいいですが、(書き方が所々おかしいが)
もし大正や明治とかも範囲に含まれていたらどうなるでしょうか。
面倒ですね。

ではどうするか。「規則性を見付ける」です。

まず、対象データ a はどのようなデータでしょうか。

[西暦][月] が文字列になったものですよね?

西暦とは? ここでは 4桁の数字ですよね。(少なくとも現代においては)

文字列の長さは6ですよね。

つまり、最初の四桁は「西暦」、残り( 6桁 - 4桁 = 2桁 )は月。

これが「西暦の長さは3桁だったり4桁だったりする」のであれば若干面倒ですが、今回は『西暦については四桁』と決まっているので、先端から4バイト分、文字列として取り出す。

そしてそれを整数(int型とか)に変換する。

そうすれば、「1926~1989年」-> 「昭和」だとわかりますね。
平成も同様に。

そうすると、「平成 or 昭和」と 「n年 or 元年」の文字列を取得すればいいです。
でも令和元年のように、中途半端な時期から(= 正月と同時に…ではない)場合もあります。
よって、「何月か」も必要になります。

なので「月」に相当する部分も整数にしておく。

そうすれば、西暦用の変数と月用の変数で「年号」がわかる。

で、後は「季節」ですが、これもパターンがあります。

夏はいつからいつまで? 春はいつからいつまで? それを考えるとわかるはずです。
これも「月」を表す整数で考えればいいだけです。

そうすれば、

1. ユーザ入力を受け付けて、配列aに入れる 2. 西暦の部分と月の部分をそれぞれ整数にする 3. (2)の値から「年号」を計算する 4. (2)の「月」の値から「季節」を計算する 5. (3),(4)で取得したデータを出力する

これだけで済みます。
実際にはもうちょっとひねらないといけませんが、ほぼこの方向性でいいはずです。

後は(3)の部分をどのように実装するかを同じように分解したりして考える。
(4)も同様に。


[追記1]

具体的には、6桁の数字を配列として受け取って、その前の4バイトと後ろの2バイトに分けて、整数としてことができません。int a = array[4]{ }; int b = array[2]としても、元の配列から数字を取ってきてくれません。こういう場合は、どのように考えるのでしょうか?特に後ろ2バイトなどは表現の使用がないと思いました。

とりあえず、文字列とはなんでしょうか。そこから考える必要があります。
そう、「char型配列」ですね。

では、配列とはなんでしょうか。
イメージ的にはここのような感じでしょうか。

では文字列とはなんでしょうか。そうchar型配列ですね。

char型は内部では整数のようですが、「文字」用です。

"Hello" だと、{ 'H', 'e', 'l', 'l', 'o' } という状態です。

今回の 配列 a も たとえば 200102 であれば、{ '2', '0', '0', '1', '0', '2' } です。

で、もし現実世界で 200102 という文字がホワイトボードに書かれていて、定義は上記のように
[西暦][月] の並びでなっていると分かっているとしたら、どのように読みますか?

私なら 先頭の'2' から 4文字目(= '1' ) までを一つとして、"2001"を西暦とします。
残り、つまり 6文字 - 4文字 = 2文字、この2文字は「月」と考えます。

つまり、一文字目 '2' をホワイトボードの余白に書く。

全体: 200102 西暦: --- 月 : ---

↓ ↓ ↓ ↓ ↓  ↓

全体: *00102 西暦: 2 月 : ---

全体の一文字目はチェック済みってことで"*"とかで伏せる。(伏せなくてもいいけどわかりやすくするために)

で、2文字目もやる。

全体: **0102 西暦: 20 月 : ---

3文字目も。

全体: ***102 西暦: 200 月 : ---

4文字目も。

全体: ****02 西暦: 2001 月 : ---

で5文字目も…とやりたいところですが、西暦は4桁なので西暦はここまで。
後は月と見なす。

全体: ****** 西暦: 2001 月 : 02

一応、5文字目や6文字目に相当する部分も4文字目みたいに考える。

これで、「西暦」と「月」がそれぞれ文字列として取得できました。

よーく見てください。ホワイトボードでは、「余白に、別の文字として書いて」います。
C言語とかなら「別の配列として」いる感じですね。

char strYear[5];
char strMonth[3];
とかみたいにして。

ただし、文字列なので 桁数 + 1 ( 終端を表すデータ分を末尾に追加 ) します。

for文とかで先端( 0番目 ) から 4桁分 strYearに書き込む。最後に終端を表すデータ( "\n" かな? )を追加しておく。

5桁目からはstrMonthに入れる。最後まで。そしてstrYearと同様に末尾に\n を追加。

これで取り出せるはずです。

後は整数にするのですが、'2' は常に 2 とは限りません。
ヒント: ShiftJISの場合

なので工夫する必要があります。
ですが今回はchar型配列です。(どちらも4桁か2桁)

なので文字列を整数に変換する関数等を使えばいいです。(それについては「C言語 文字列 整数 変換」とかで検索してください)

後は基礎が出来ていれば、ちょっと工夫するだけでイケるはずです。


[追記2]

コメントにて『もしかして型がよくわかっていない可能性がある』とご指摘を受けたので、追記します。
(本来は ggれ(略) と言いたいですが。基礎中の基礎なので)

※ 私は趣味&独学なので綺麗な説明はできませんが、書いておきます。

C言語の変数には型というものがあります。

これは変数についての説明みたいなものですね。

参考文献にあるように、型によって範囲が違います。

環境によって違いますが、64bit版だと

int : -2147483648 〜 2147483647 long: -9223372036854775808 〜 9223372036854775807

となっています。

たとえば 6147483648 のようなデータを代入しようとすると、int型だと範囲を大きく超えてしまいます。
本当か? と思うのなら、数直線を書いていみるとわかるはずです。

ではどうするか、intより大きいデータを扱える型を使うのです。

int a = "2147483647" …ではなく、long a = "2147483647" と言う風に。

数直線を意識するとわかるはずです。
この対象にしている範囲を定義しているのが型です。

intはここからここまで、unsigned intはここからここまで。と言う風に。

char型は中身は整数です。
参考: Shift-JISの表

printf関数とかが表示するときに文字にしているだけのようです。

そして、配列はその変数が連なったイメージです。(上で挙げたURL先にあるような感じ)

後は上(本回答や追記1等)を読み返してください。

投稿2021/10/08 12:34

編集2021/10/09 06:51
BeatStar

総合スコア4958

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

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

Miu-ktym

2021/10/08 12:52

はい!自分でも、プログラミングは全くわかっていないので、基礎からやっていきたいと思っています。 具体的には、6桁の数字を配列として受け取って、その前の4バイトと後ろの2バイトに分けて、整数としてことができません。int a = array[4]{ }; int b = array[2]としても、元の配列から数字を取ってきてくれません。こういう場合は、どのように考えるのでしょうか?特に後ろ2バイトなどは表現の使用がないと思いました。 全くの初心者の質問で申し訳ありません。でも、プログラミングは諦めたくないので時間がかかっても1つずつ基礎を覚えていきたいと思っています。よろしくお願いします。
fana

2021/10/09 01:54

ロジックの話をするまえに, まずは【C言語の文法】を相応に学ぶべきではないかと見えます. C言語を用いるのであれば.
BeatStar

2021/10/09 02:01

@ fanaさん > ロジックの話をするまえに, ですね。私もそう思って最初に『基礎から』と書いていますが、伝わっていないようなのでちょっと修正します。
dodox86

2021/10/09 02:17

老婆心からですが、たぶん質問者さんはcharとかintとかなどの型、それを踏まえての配列の違いも理解されていないので、本当に基本からやらないとせっかくの回答での説明も徒労に終わってしまう可能性が高いと思います。
BeatStar

2021/10/09 06:28

@ dodox86さん > たぶん質問者さんはcharとかintとかなどの型、 そんなまさか……と思い、読み返してみると確かにその可能性が高いですね。 追記しておきます。
dodox86

2021/10/09 07:27

[追記2]を読んで ああ、いえ、BeatStarさんにC言語の基本を教えてもらって、という意味ではなかったのですが、、、「基本からやらないと」と言うのは、「基本から教えてあげて」という意味ではなく、質問者さん自身が基本からやらないと、という意味でした。誤解を与えてしまったのであればすみません。 (C言語教室ではないので、数値の範囲まで教えていたらきりがないですよね。<それが質問だったらアリですが)
BeatStar

2021/10/09 07:51 編集

@ dodox86さん あ、私に対してじゃなかったんですか…… まあ、書いたものを消すのはアレなのでそのままにしておきます。
guest

0

あまりにイロイロ間違って仕舞われています。
件名の元となっている配列の部分でさえも、

c

1 int a[6]; 2 scanf("%d", &a);

としていては、そもそも配列 a の各要素には各桁毎の値は入っておりません。
先ず scanf から確実にされたほうが宜しいかと思います。
(とはいえ、実は scanf はポインタ等の話で結構難しいモノなのですけど…。)

投稿2021/10/08 14:03

編集2021/10/08 14:04
jimbe

総合スコア12756

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

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

0

C

1#include <stdio.h> 2 3int main() { 4 5 int input; 6 int year; 7 int month; 8 9 printf("6桁の数字を入力して下さい。 "); 10 scanf("%d",&input); 11 12 year = input / 100; /* アタマの4桁 */ 13 month = input % 100; /* ケツの2桁 */ 14 15 printf("year=%d, month=%d\n", year, month); 16 17 /* あとはまかせた! */ 18 19 return 0; 20}

投稿2021/10/08 23:31

episteme

総合スコア16614

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

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

0

ちゃんと考えれば良いと思います。

投稿2021/10/08 19:54

qqfsdfsafd

総合スコア599

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

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

0

まず、目についたところで、、、

a[0,1,2,3]

C言語で、このように書くと、a[3] (最後の 3が有効)と見なされます。
何をしたいか、ちょっと読み取れないですが、まずは、入力した数字を表示(出力)することから、始めましょう。

投稿2021/10/08 10:46

pepperleaf

総合スコア6383

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

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

Miu-ktym

2021/10/08 12:39

自分でもプログラミングが苦手で、全く基礎ができていないのことは理解できています。でも、諦めたくないので入力した数字を出力するところからやっていきたいと思います。ありがとうがざいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問