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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

3729閲覧

fgets関数においての桁数処理

Hinomae

総合スコア7

C

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/05/15 11:07

編集2020/12/21 06:01

前提・実現したいこと

<Luhnアルゴリズム>
入力されたある桁数の整数について、右から偶数番目の数を2倍し、もし2倍した結果が10以上であればその数の1の位と10の位を足す。
結果的にすべての位を合計した数の1の位が0であれば「true」、そうでなければ「false」を出力する。

また(1)入力された数が60桁を超える時 (2)入力に0~9以外の文字が含まれるとき
は「Error」を出力する。
includeしていいのは<stdio.h>のみとする。

例:入力→1234567
このとき1 + 4 + 3 + 8 + 5 + (1+2) + 7 = 31
よって出力→false

このプログラムで条件(1)を満たすような条件式が分かりません。

・Lは入力された整数の桁数、moji[]は入力された一文字一文字をそれぞれ格納するものです。
・2倍や足し算といった計算をする為にchar型の変数を一度「-'0'」を付け足しASCIIコードと対応させて行っています。
・inv関数は入力に数字以外が入っていないか判別するものです。入力がすべて数字であれば1,一文字でもabcといった文字が含まれていれば0を返します。(条件(2))

今まで大学からの課題などで入力を読み取るのにscanfを使ってきたので、このプログラムで初めてfgetsを使っています。
仮に60桁の数が入力された場合、fgets関数によりmoji[0]~moji[59]に数字、そしてmoji[60]に\0が入りmoji[61]以降は全て'\0'が格納されると考え、条件(1)を満たすような条件文を(moji[61]!='\0')としたのですが、入力する数が同じでもコンパイル毎に結果が変わってしまいます。
(合計の1の位が0ならtrueかErrorのどちらか、そうでないならfalseかErrorのどちらか)

条件(2)の判別をするinv関数は正しく機能しており、sumの値も問題ありません。
ただ実行結果が一定にならないということなのでおそらくmoji[61]!='\0'という条件文に問題があると思います。
fgets関数の理解が甘い上で質問させていただきますが、出力結果が一定になる条件文を探しています。m(__)m

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

該当のソースコード

C

1#include <stdio.h> 2 3int L; 4 5int inv(int x[]) 6{ 7 int i,A; 8 9 for(i=0; i<L; ++i){ 10 if(x[i]<0 || x[i]>9){ 11 A=0; 12 break; 13 }else{ 14 A=1; 15 } 16 } 17 return A; 18} 19 20int main(void) 21{ 22 int i,num[100],c[100],sum=0; 23 char moji[100]; 24 25 fgets(moji,100,stdin); 26 27 for(i=0; i<100; ++i){ 28 if(moji[i]=='\0'){ 29 L=i-1; 30 break; 31 } 32 } 33 34 for(i=0; i<L; ++i){ 35 num[i]=moji[i]-'0'; 36 } 37 38 for(i=1; i<=L; ++i){ 39 c[i]=moji[L-i]-'0'; 40 } 41 42 if(inv(num)==0){ 43 printf("Error\n"); 44 }else{ 45 for(i=1; i<=L; ++i){ 46 if(i%2==0){ 47 c[i]=c[i]*2; 48 if(c[i]>9){ 49 c[i]=c[i]-9; 50 } 51 } 52 sum=sum+c[i]; 53 } 54 55 if(moji[61]!='\0'){ 56 printf("Error\n"); 57 }else if(sum%10==0){ 58 printf("true\n"); 59 }else{ 60 printf("false\n"); 61 } 62 } 63}

試したこと

条件(1)の対処としてmoji[61]!='\0'を適用してみました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

gentaro

2020/05/15 11:45

課題は自力でやりましょう。 わからなければ先生に質問しましょう。 https://teratail.com/help/avoid-asking 「何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。」
guest

回答3

0

ベストアンサー

fgets関数の理解が甘い

そう思うのなら、仕様を確認しましょう→fgets
・・・思い込みは良くない・・・

投稿2020/05/15 12:00

cateye

総合スコア6851

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

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

0

仮に60桁の数が入力された場合、fgets関数によりmoji[0]~moji[59]に数字、そしてmoji[60]に\0が入りmoji[61]以降は全て'\0'が格納されると考え

間違ってます。「moji[0]~moji[59]に数字」は合ってます。
moji[60]'\n'(改行文字)で、moji[61]0で、moji[62]以降は不変(その前の内容を保つ)です。

投稿2020/05/15 11:14

otn

総合スコア84557

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

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

0

文字列の操作をうまくやるコツになりますが、真っ先に異常な文字がないか探索することと、文字列の長さを求めること、fgetsを使った場合は改行文字をNULL文字('\0')に置換することをやると良いです。こうすると文字列をなんども最初から探索しなくて済むので実行時間も短くなりますし(高々60文字なら今回は個々は関係ないですが)、コードもわかりやすくなります。なぜならエラーを先に弾けるからです。

投稿2020/05/16 13:50

yumetodo

総合スコア5850

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問