「名前」「住所」「生年月日」「電話」の四つの項目を持った構造体を定義し、
それぞれの項目にデータを入力しなさい。
また、最大文字数は、名前全角10文字、住所全角64文字、生年月日半角10文字、電話半角16文字とする。
※名前は必ず必要な項目である為、必須入力とする。
※生年月日は半角スラッシュ「/」区切りで、半角数字と半角スラッシュ以外の文字はエラーとする。
※生年月日は、日付の妥当性は考慮しない。
※電話は半角ハイフン「-」区切りで、半角数字と半角ハイフン以外の文字はエラーとする。
構造体の課題
Re:構造体の課題
まず少しずつ作ってみましょう。
では、
1:入力は改行で区切るとして、改行が行われるまで文字列に入力データを入れるだけの関数を作って下さい
これが出来たら、今度は
2:その関数に文字列の最大数も渡してやり、オーバーフローになるとエラーになる関数にして下さい。
そして最後に更に
3:そのデータの中に0~9または/以外が入っていたらエラーになる関数にして下さい。
こうしていけば解るはずだと思います。
下に参考に答えを書きますので、最初はこれを見ないで自分でやってみてから答え合わせしてみて下さい。
電話番号もこれと同じ考え方で出来ます。
/* 1の解答例* /
#include <stdio.h>
int get_str(char str[/url]){
int c,i;
i=0;
while((c=getchar())!='\n'){//改行が来るまでループ
str=c;//文字を格納し
i++;//加算
}
str='\0';//最後に終端記号を入れる
return 0;//返り値を返す
}
void main(){
char str0[11];//文字列用意
get_str(str0);//関数を呼ぶ
printf("%s",str0);
}
実行結果例
1984/09/26
1984/09/26
/* 2の解答例* /
#include <stdio.h>
#define STR0MAX 10 //文字列の長さ(実際の文字の長さで終端記号は含まない)
int get_str(char str[/url], int n){
int c,ret=0,i;
i=0;
while((c=getchar())!='\n'){//改行が来るまでループ
//オーバーフローしているなら
if(i>=n){
ret = -1;//エラー
}
else{//そうじゃなかったら
str=c;//文字を格納し
i++;//加算
}
}
str='\0';//最後に終端記号を入れる
return ret;//返り値を返す
}
void main(){
char str0[STR0MAX+1];//文字列用意
if(get_str(str0,STR0MAX)==-1)//関数を呼ぶ
printf("エラー\n");
else
printf("%s",str0);
}
実行結果例
1984/09/2666
エラー
/* 3の解答例* /
#include <stdio.h>
#define STR0MAX 10 //文字列の長さ(実際の文字の長さで終端記号は含まない)
int get_str(char str[/url], int n){
int c,ret=0,i;
i=0;
while((c=getchar())!='\n'){//改行が来るまでループ
//オーバーフローしているか、0~9または/以外なら
if(i>=n || !(c>='0' && c<='9' || c=='/')){
ret = -1;//エラー
}
else{//そうじゃなかったら
str=c;//文字を格納し
i++;//加算
}
}
str='\0';//最後に終端記号を入れる
return ret;//返り値を返す
}
void main(){
char str0[STR0MAX+1];//文字列用意
if(get_str(str0,STR0MAX)==-1)//関数を呼ぶ
printf("エラー\n");
else
printf("%s",str0);
}
実行結果例
1984/09-26
エラー
Re:構造体の課題
環境が不明なので、推測でしかないのですが…
入力にはscanfを使用するものと考えて、単純に入力を抑止するだけならば…
scanf("%[0123456789[/url]", buf);
こんな書き方もできますが、『エラーとする』とありますので、判定のする必要があるかな?
電話番号もほぼ同じ方法で判定できますんで、がんばってください。
入力にはscanfを使用するものと考えて、単純に入力を抑止するだけならば…
scanf("%[0123456789[/url]", buf);
こんな書き方もできますが、『エラーとする』とありますので、判定のする必要があるかな?
int IsBirthday(char* pbuf) { for (unsigned int i = 0; i < strlen(pbuf); ++i) { if (isdigit((int)(*(pbuf + i))) == 0) { continue; } else if (*(pbuf + i) != '/') { return 0; } } return 1; }関数化してみました。引数の文字列に数字とスラッシュ以外が見つかると0を返し、見つからなかった場合は1を返します。コンパイルしてないので、エラーが出たらごめんなさい。
電話番号もほぼ同じ方法で判定できますんで、がんばってください。
Re:構造体の課題
ツンデレサンプルです。
main関数は用意してません。
色々間違いがあるかもなのでその辺は許してください
main関数は用意してません。
色々間違いがあるかもなのでその辺は許してください
#include<stdio.h> #include<conio.h> typedef struct{ char name[21]; char address[129]; char birthday[11]; char phone[16]; }DATA,*LPDATA; void MyGets(char *buf,int len); //文字列の入力 int JudgeStr(char *str,char *JudgeStr); //JudgeStr内の文字のみの文字列か void MyGetData(LPDATA lpData); //データの入力(ツンデレ) int main(){ DATA data; MyGetData(&data); getch(); return 0; } void MyGets(char *buf,int len){ //lenはNULL文字含む文字数 int ch; while(--len){ ch=getchar(); if(ch==EOF || ch=='\n') break; else *buf++=(char)ch; } *buf='\0'; } int JudgeStr(char *str,char *JudgeStr){ int i; while(*str){ for(i=0;JudgeStr;i++) if(JudgeStr == *str) break; if(!JudgeStr) return 0; str++; } return 1; } void MyGetData(LPDATA lpData){ puts("名前を入力しなさいよっ、ふん"); while(1){ MyGets(lpData->name,sizeof(lpData->name)); if(!JudgeStr(lpData->name," \t\n\r\f\v")) break; puts("ちゃんと入力しなさいよ!!\n" "……べ、別に長引いたって嬉しくないんだからねっ!"); } puts("住所を入力しなさい!!"); MyGets(lpData->address,sizeof(lpData->address)); puts("電話番号を入力しなさい!!・・・あ、あなたに電話したいなんて言ってないわよ!?"); while(1){ MyGets(lpData->phone,sizeof(lpData->phone)); if(JudgeStr(lpData->phone,"0123456789-")) break; puts("ちゃんと入力しなさいよ!!\n" "べ、別に長引いたって嬉しくなんてないんだからねっ……"); } puts("生年月日を教えなさ・・・っ入力しなさい!"); while(1){ MyGets(lpData->birthday,sizeof(lpData->birthday)); if(JudgeStr(lpData->birthday,"0123456789/")) break; puts("ちゃんと入力しなさいよ!!\n" "べ、別に長引いたって嬉しくなんてないんだからねっ……"); } puts("終わりよ。\n" "ま、また訊いて欲しければ訊いてやってもいいわよ・・・"); }