🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

4回答

1978閲覧

HH:MM:SSのチェック C言語

gekko

総合スコア16

C

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

0グッド

0クリップ

投稿2019/11/01 18:11

編集2019/11/01 22:57

HH:MM:SSのフォーマットのチェックと時間が有効かどうかのプログラムを書いてます。アウトプットまたは判定のところででミスがあると思われるのですが、見つからなくて困っています。。

C

1#include <stdio.h> 2#include <string.h> 3int input(char text[]); 4void timecheck(int a, char array1[a][8], int f[a]); 5void lettercheck(int b, char array2[b][8], int g[b]); 6void formatcheck(int c, char array3[c][8], int h[c]); 7void numbercheck(int d, char array4[d][8], int j[d]); 8void output(int e, char array5[e][8], int k[e]); 9int main(void){ 10 int N, i; 11 N = input("N:"); 12 char timestamps[N][81]; 13 int check[N]; 14 for(i=0;i<N;i++){ 15 do{ 16 scanf("%s", timestamps[i]); 17 }while(strlen(timestamps[i])!=8); 18 } 19 20 timecheck(N, timestamps, check); 21 output(N, timestamps, check); 22 return 0; 23} 24int input(char text[]){ 25 int x; 26 printf("%s", text); 27 scanf("%d", &x); 28 return x; 29} 30void timecheck(int a, char array1[a][8], int f[a]){ 31 formatcheck(a, array1, f); 32 lettercheck(a, array1, f); 33 numbercheck(a, array1, f); 34} 35 36void formatcheck(int b, char array2[b][8], int g[b]){ 37 int i; 38 for(i=0;i<b;i++){ 39 if(array2[i][2]==':' && array2[i][5]==':' && array2[i][0] != ':' && array2[i][1] != ':' && array2[i][3]!=':' && array2[i][4]!=':' && array2[i][6]!=':' && array2[i][7]!=':'){ 40 continue; 41 }else{ 42 g[i]=4; 43 } 44 } 45} 46 47 48void lettercheck(int c, char array3[c][8], int h[c]){ 49 int i; 50 for(i=0;i<c;i++){ 51 if(h[c]==4){ 52 continue; 53 } 54 if(array3[i][0] >= 'a' && array3[i][0] <= 'z'){ 55 h[i] = 2; 56 } 57 else if(array3[i][1] >= 'a' && array3[i][1] <= 'z') { 58 h[i] = 2; 59 } 60 else if(array3[i][3] >= 'a' && array3[i][3] <= 'z') 61 { 62 h[i] = 2; 63 } 64 else if(array3[i][4] >= 'a' && array3[i][4] <= 'z') { 65 h[i] = 2; 66 } 67 else if(array3[i][6] >= 'a' && array3[i][6] <= 'z'){ 68 h[i] = 2; 69 } 70 else if(array3[i][7] >= 'a' && array3[i][7] <= 'z'){ 71 h[i] = 2; 72 } 73 } 74} 75void numbercheck(int d, char array4[d][8], int j[d]){ 76 int i; 77 for(i = 0; i < d; i++){ 78 if(j[i]==2 || j[i]==4){ 79 continue; 80 } 81 if(((array4[i][0]=='0' || array4[i][0]=='1') && array4[i][1]>='0' && array4[i][1]<='9') || (array4[i][0]=='2' && (array4[i][1]>='0' && array4[i][1]<='4'))){ 82 if((array4[i][3]>='0' && array4[i][3]<='5') && (array4[i][4]>='0' && array4[i][4]<='9')){ 83 if((array4[i][6]>='0' && array4[i][6]<='5') && (array4[i][7]>='0' && array4[i][7]<='9')){ 84 j[i]=1; 85 }else{ 86 j[i] = 3; 87 } 88 }else{ 89 j[i] = 3; 90 } 91 }else{ 92 j[i]=3; 93 } 94 } 95} 96 97void output(int e, char array5[e][8], int k[e]){ 98 int i; 99 for(i=0;i<e;i++){ 100 if(k[i]==1){ 101 printf("%s", array5[i]); 102 printf(" correct time\n"); 103 }else if(k[i]==2){ 104 printf("%s", array5[i]); 105 printf(" valid format\n"); 106 }else if(k[i]==3){ 107 printf("%s", array5[i]); 108 printf(" incorrect time\n"); 109 }else if(k[i]==4){ 110 printf("%s", array5[i]); 111 printf(" invalid format\n"); 112 } 113 } 114} 115 116 117 118 119 120 121 122 123

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

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

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

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

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

y_waiwai

2019/11/01 22:27

現状のコードではどういうふうに動作するんでしょうか
gekko

2019/11/01 22:32

N:3 11:22:33 aa?dd?44 55555555 11:22:33 correct time invalid format 8'��� invalid format こんな感じです
gekko

2019/11/01 22:34

一個目はちゃんと入力したものを返すんですが、2個めからなくなり、3個めは意味わかんなくなってしまいます、、、
guest

回答4

0

ベストアンサー

問題点1
以下のようにtimestampsは、81桁確保しているので
char timestamps[N][81];
各関数のtimestampのサイズを以下のように81桁にしてください。
void timecheck(int a, char array1[a][81], int f[a]);
void lettercheck(int b, char array2[b][81], int g[b]);
void formatcheck(int c, char array3[c][81], int h[c]);
void numbercheck(int d, char array4[d][81], int j[d]);
void output(int e, char array5[e][81], int k[e]);
そうしないと、2つ目からのtimstampsの位置がずれてきます。

尚、わかっているとは思いますがtimestamps側を合わせようとして
char timestamps[N][8];
としてはいけません。scanfでは文字列の最後にnullが格納されるので、最低でも9桁は必要ですから。

問題点2
lettercheckで数字であるべきところにa~zが入力されたらエラーとしていますが
他の文字が入力された場合を考慮していません。
例えば
aa:aa:aaはvalid formatですが
AA:AA:AAはincorrect timeになります。

数字であるべきところにa~zが入力されたらではなく、0~9以外の文字が入力されたらに変えてください。

投稿2019/11/01 23:51

tatsu99

総合スコア5493

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

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

gekko

2019/11/01 23:54

ありがとうございます!!
guest

0

ツッコミどころはたくさんありますが、明らかにおかしいところを指摘しておきます

int check[N];

この配列は初期化されないまま使用されてますね
ローカル変数は最初にはデタラメの値が入ってます

入力文字列のバッファ配列は、

char timestamps[N][81];

こう定義されてるのに、それを受ける関数の引数はすべて、

void timecheck(int a, char array1[a][8], int f[a]);

void lettercheck(int b, char array2[b][8], int g[b]);
void formatcheck(int c, char array3[c][8], int h[c]);
void numbercheck(int d, char array4[d][8], int j[d]);
void output(int e, char array5[e][8], int k[e]);

となってしまっています。
型があってないので、関数の方では文字列配列を正常に受け取れていません

投稿2019/11/01 23:31

y_waiwai

総合スコア88038

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

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

gekko

2019/11/01 23:55

ありがとうございます!
guest

0

C可変長の配列↓が利用できるのは
char timestamps[N][81];
int check[N];
は、特定のコンパイラのみです、
C言語(C11)で可変長の配列を使う方法
また、↑にも有りますが、C++14の仕様には含まれていません。

で、フォーマットチェックは下記で出来るのでは?
if(scanf("%d:%d:%d",&h,&m,&s) != 3){
エラー処理
}

『追記』BAが出ていますが、取り敢えず^^

text

1usr ~/Project/test % ./a.out 2N:? 3 312:34:56 423:59:00 520:00:60 612:34:56 7 8 correct time 9 1023:59:00 11 12 correct time 13 1420:00:60 15 16 incorrect time

c

1#include <stdio.h> 2#include <string.h> 3#include <ctype.h> 4// 5#define ARRY_SIZE (64) 6 7int input(void); 8void timecheck(int a, const char array[][ARRY_SIZE], int f[]); 9int lettercheck(const char array[ARRY_SIZE]); 10int formatcheck(const char array[ARRY_SIZE]); 11int numbercheck(const char array[ARRY_SIZE]); 12void output(int e, char array[][ARRY_SIZE], int k[]); 13enum { 14 NML_END, 15 CorrectTime, 16 ValidFormat, 17 IncorrectTime, 18 InvalidFormat 19}; 20 21int main(void) 22{ 23 int N, i; 24 N = input(); 25 char timestamps[N][ARRY_SIZE]; 26 int check[N]; 27 for (i = 0; i < N; i++) { 28 check[i] = NML_END; 29 fgets(timestamps[i], ARRY_SIZE, stdin); 30 } 31 32 timecheck(N, timestamps, check); 33 output(N, timestamps, check); 34 return 0; 35} 36// 37int input(void) 38{ 39 int x; 40 fputs("N:? ", stdout); 41 scanf("%d\n", &x); 42 return x; 43} 44// 45void timecheck(int a, const char array[][ARRY_SIZE], int f[]) 46{ 47 for (int i = 0; i < a; i++) { 48 // puts("formatcheck"); 49 if ((f[i] = formatcheck(array[i])) == CorrectTime) { 50 // puts("lettercheck"); 51 if ((f[i] = lettercheck(array[i])) == CorrectTime) { 52 // puts("numbercheck"); 53 f[i] = numbercheck(array[i]); 54 } 55 } 56 } 57} 58 59int formatcheck(const char array[]) 60{ 61 int h, m, s; 62 if (sscanf(array, "%2d:%2d:%2d", &h, &m, &s) != 3) { 63 // puts(array); 64 return InvalidFormat; 65 } 66 // printf("%2d-%2d-%2d\n",h,m,s); 67 return CorrectTime; 68} 69 70int lettercheck(const char array[]) 71{ 72 const static int pos[] = {0, 1, 3, 4, 6, 7}; 73 74 for (int i = 0; i < 5; i++) { 75 if (!isdigit(array[pos[i]])) { 76 return ValidFormat; 77 } 78 } 79 return CorrectTime; 80} 81 82int numbercheck(const char array[]) 83{ 84 85 if (!isdigit(array[0]) || array[0] > '2') { 86 // puts("1"); 87 return IncorrectTime; 88 } 89 if (!isdigit(array[1])) { 90 // puts("2"); 91 return IncorrectTime; 92 } 93 if (!isdigit(array[3]) || array[3] > '5') { 94 // puts("3"); 95 return IncorrectTime; 96 } 97 if (!isdigit(array[4])) { 98 // puts("4"); 99 return IncorrectTime; 100 } 101 if (!isdigit(array[6]) || array[6] > '5') { 102 // puts("5"); 103 return IncorrectTime; 104 } 105 if (!isdigit(array[7])) { 106 // puts("6"); 107 return IncorrectTime; 108 } 109 110 return CorrectTime; 111} 112 113void output(int e, char array[][ARRY_SIZE], int k[]) 114{ 115 for (int i = 0; i < e; i++) { 116 if (k[i] == CorrectTime) { 117 puts(array[i]); 118 puts(" correct time\n"); 119 } else if (k[i] == ValidFormat) { 120 puts(array[i]); 121 puts(" valid format\n"); 122 } else if (k[i] == IncorrectTime) { 123 puts(array[i]); 124 puts(" incorrect time\n"); 125 } else if (k[i] == InvalidFormat) { 126 puts(array[i]); 127 puts(" invalid format\n"); 128 } 129 } 130} 131

修正すべき所は多々有ると思いますが、まあ動くので・・・
#いろいろなフォーマットのテストをされたほうが良いと思います。

投稿2019/11/01 18:24

編集2019/11/02 02:27
cateye

総合スコア6851

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

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

gekko

2019/11/01 18:26

そこには文字も入る可能性があるので文字列で判定してます
gekko

2019/11/01 18:37

たびたびすみません。もし':'がちゃんとした位置にあっても文字が入っていた場合はvalid formatと返さなくてはいけないのでintで扱えないと思ったのですが、、、
cateye

2019/11/01 18:53 編集

"valid format"ですか?・・・"invalid format"ではなく? 文字列の場合でもsscanf()が使えます。
cateye

2019/11/01 18:49 編集

無効なフォーマット(invalid format)であれば、上記scanf()で読めないので拾えますが? ・・・てか、このソースコンパイルできますか?
cateye

2019/11/01 19:17 編集

〉判定のなかでミスがあると思われる usr ~/Project/test % ./a.out N:2 12:30:40 21:10:22 12:30:40 correct time invalid format ・・・21時がはねられるのは? usr ~/Project/test % ./a.out N:2 1:30:5 24:00:00 1:30:51:30:5 invalid format invalid format 1桁はダメ?・・・24時を許容するかどうかは、決めごとですが・・・
gekko

2019/11/01 19:16

コンパイルはできます
gekko

2019/11/01 19:18

時間が間違ってたらincorrect time 合ってたらcorrect time 文字ががはいってても:が正しいいちなら valid format :がおかしい位置ならinvalid formatって返すコードを書こうとしてます
gekko

2019/11/01 22:35

1桁ははじくようにしました。
cateye

2019/11/02 02:46

デバッグ用のputs()やらprintf()は残してあります。必要ならコメントを外して下さい。
gekko

2019/11/02 09:42

ありがとうございます????????????????
guest

0

可変長配列がサポートされていないコンパイラの場合 malloc を使うとよいでしょう。

C

1#include <stdio.h> // scanf, sscanf, printf 2#include <stdlib.h> // malloc, free 3#include <string.h> // strlen 4#include <ctype.h> // isdigit 5 6#define SIZE 81 7#define FMT "%80s" 8 9int input(char text[]); 10void timecheck(int n, char array[][SIZE], int check[]); 11void output(int n, char array[][SIZE], int check[]); 12 13enum { CORRECT_TIME = 1, VALID_FORMAT, INCORRECT_TIME, INVALID_FORMAT }; 14 15int main(void) 16{ 17 int N = input("N:"); 18 char (*timestamps)[SIZE] = malloc(SIZE * N); 19 int *check = malloc(sizeof(int) * N); 20 for (int i = 0; i < N; i++) scanf(FMT, timestamps[i]), check[i] = 1; 21 timecheck(N, timestamps, check); 22 output(N, timestamps, check); 23 free(timestamps), free(check); 24 return 0; 25} 26 27int input(char text[]) 28{ 29 int x; 30 printf("%s", text); 31 scanf("%d", &x); 32 return x; 33} 34 35void timecheck(int n, char array[][SIZE], int check[]) 36{ 37 char c; int h, m, s; 38 for (int i = 0; i < n; i++) 39 if (strlen(array[i]) != 8 || array[i][2] != ':' || array[i][5] != ':') 40 check[i] = INVALID_FORMAT; 41 else if (sscanf(array[i], "%*2[0-9]:%*2[0-9]:%*1[0-9]%c", &c) != 1 || !isdigit(c)) 42 check[i] = VALID_FORMAT; 43 else if (sscanf(array[i], "%d:%d:%d", &h, &m, &s), h >= 24 || m >= 60 || s >= 60) 44 check[i] = INCORRECT_TIME; 45} 46 47void output(int n, char array[][SIZE], int check[]) 48{ 49 for (int i = 0; i < n; i++) 50 switch (check[i]) { 51 case CORRECT_TIME: printf("%s correct time\n", array[i]); break; 52 case VALID_FORMAT: printf("%s valid format\n", array[i]); break; 53 case INCORRECT_TIME: printf("%s incorrect time\n", array[i]); break; 54 case INVALID_FORMAT: printf("%s invalid format\n", array[i]); break; 55 } 56}

25:00:00 や 12:34:567 もチェックします。

投稿2019/11/04 00:40

kazuma-s

総合スコア8224

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問