Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.47 KB | None | 0 0
  1. /*
  2. 電話帳ソフトウェア
  3. 作成者
  4. 2ei
  5. 22 中村勇介
  6. 31 牧田光平
  7. */
  8.  
  9. #include<stdio.h>
  10. #include<stdlib.h>
  11. #include<string.h>
  12. #include<conio.h>
  13.  
  14. #define NUMBER_OF_USERS 256     //ユーザー数
  15. #define ERROR_FILE "ファイルエラーが発生したので強制終了します\n"  //エラーメッセージ
  16. #define DELETE_CL( a ) ( pointer )->a[ strlen( ( pointer )->a ) - 1 ] = '\0'    //改行の削除
  17. #define FILE_NAME "userdata.txt"    //ユーザデータ格納txtファイル名
  18.  
  19. /*電話帳に登録される情報の構造体*/
  20. struct userdata
  21. {
  22.     /*氏名格納*/
  23.    
  24.     char first_name[256];       //名
  25.     char last_name[256];        //姓
  26.    
  27.     /*フリガナ格納(アルファベットで氏名を格納する場合は不要)*/
  28.     char first_name_phonetic[256];  //名のフリガナ
  29.     char last_name_phonetic[256];   //姓のフリガナ
  30.    
  31.     /*電話番号格納。ハイフンを想定してchar型で格納する。*/
  32.     char phone_number1[256];        //電話番号1
  33.     char phone_number2[256];        //電話番号2
  34.     char phone_number3[256];        //電話番号3
  35.    
  36.     /*メールアドレス格納*/
  37.     char mail_address1[256];        //メールアドレス1
  38.     char mail_address2[256];        //メールアドレス2
  39.     char mail_address3[256];        //メールアドレス3
  40.    
  41.     /*住所格納。郵便番号は個別で保持*/
  42.     char zip_code[256];     //郵便番号
  43.     char address[256];      //住所
  44.    
  45.     /*グループ格納*/
  46.     char group[256];
  47.    
  48. };
  49.  
  50.  
  51. void DeleteNewLine( struct userdata *pointer );                 //改行を削除
  52. void DispUserDetail( struct userdata *pointer );                //登録されているユーザーの情報を表示
  53. void Sort4Phonetic( void );                                     //フリガナを利用したソート関数
  54. void Sort4Group( void );                                        //グループ別ソート関数
  55. void DispData( struct userdata *pointer , int user );           //電話帳表示(氏名のみ)
  56. int AddNewUser( struct userdata *pointer , int user );          //新規ユーザデータ作成
  57. int ReadUserData( struct userdata *pointer );                   //txtからユーザーデータを読み込む
  58. int CheckTxtFile( void );                                       //txtファイルの有無をチェック
  59. int Menu( struct userdata *pointer , int user , int *user_p );  //メニュー表示
  60. int WriteUserData2Txt( struct userdata *pointer , int user );   //すべてのデータをtxtファイルに書き込む
  61.  
  62.  
  63. /*現在構造体配列に格納されているすべてのデータをtxtファイルに出力する
  64. ファイルを新規作成し、先頭から書き込む。
  65. 正常に書き込めた場合、書き込んだユーザー数を返す*/
  66. int WriteUserData2Txt( struct userdata *pointer , int user )
  67. {
  68.     FILE *file_p;
  69.    
  70.     int num;
  71.    
  72.     //ファイル作成エラーの場合
  73.     if ( ( file_p = fopen( FILE_NAME , "w" ) ) == NULL )
  74.     {
  75.         //エラー出力
  76.         printf( ERROR_FILE );
  77.        
  78.         //強制終了
  79.         exit( EXIT_FAILURE );
  80.     }
  81.    
  82.     else;
  83.    
  84.     //書き込み処理
  85.     for( num = 0; num < user; num++ )
  86.     {
  87.         //データ区切り線書き込み
  88.         //fprintf( file_p , "-\n" );
  89.         fputs( "-", file_p );
  90.        
  91.         //情報を構造体のメンバに書き込む
  92.         fprintf( file_p , "%s\n" , ( pointer + num )->first_name );             //名
  93.         fprintf( file_p , "%s\n" , ( pointer + num )->last_name );              //姓
  94.        
  95.         fprintf( file_p , "%s\n" , ( pointer + num )->first_name_phonetic );    //名フリガナ
  96.         fprintf( file_p , "%s\n" , ( pointer + num )->last_name_phonetic ); //姓フリガナ
  97.        
  98.         fprintf( file_p , "%s\n" , ( pointer + num )->phone_number1 );          //電話番号1
  99.         fprintf( file_p , "%s\n" , ( pointer + num )->phone_number2 );          //電話番号2
  100.         fprintf( file_p , "%s\n" , ( pointer + num )->phone_number3 );          //電話番号3
  101.        
  102.         fprintf( file_p , "%s\n" , ( pointer + num )->mail_address1 );          //メールアドレス1
  103.         fprintf( file_p , "%s\n" , ( pointer + num )->mail_address2 );          //メールアドレス2
  104.         fprintf( file_p , "%s\n" , ( pointer + num )->mail_address3 );          //メールアドレス3
  105.        
  106.         fprintf( file_p , "%s\n" , ( pointer + num )->zip_code );               //郵便番号
  107.         fprintf( file_p , "%s\n" , ( pointer + num )->address );                //住所
  108.        
  109.         fprintf( file_p , "%s\n" , ( pointer + num )->group );                  //グループ
  110.        
  111.     }
  112.    
  113.     //ファイルクローズ
  114.     fclose( file_p );
  115.    
  116.     //書き込んだユーザ数を返却
  117.     return num;
  118. }
  119.  
  120. /*新規ユーザデータを配列の要素の空き要素に追加
  121. 構造体配列のアドレス、現在登録されているユーザー数を引数として受け取る
  122. ユーザーデータが作成された場合は1を返し、これをユーザ数に追加する必要がある*/
  123. int AddNewUser( struct userdata *pointer , int user )
  124. {
  125.     printf("新規ユーザを登録します\n");
  126.    
  127.     printf("姓:");                         scanf( "%s" , ( pointer + user )->last_name );
  128.     printf("名:");                         scanf( "%s" , ( pointer + user )->first_name );
  129.    
  130.     printf("姓フリガナ(英語):");         scanf( "%s" , ( pointer + user )->last_name_phonetic );
  131.     printf("名フリガナ(英語):");         scanf( "%s" , ( pointer + user )->first_name_phonetic );
  132.    
  133.     printf("電話番号1:");                   scanf( "%s" , ( pointer + user )->phone_number1 );
  134.     printf("電話番号2:");                   scanf( "%s" , ( pointer + user )->phone_number2 );
  135.     printf("電話番号3:");                   scanf( "%s" , ( pointer + user )->phone_number3 );
  136.    
  137.     printf("メールアドレス1:");              scanf( "%s" , ( pointer + user )->mail_address1 );
  138.     printf("メールアドレス2:");              scanf( "%s" , ( pointer + user )->mail_address2 );
  139.     printf("メールアドレス3:");              scanf( "%s" , ( pointer + user )->mail_address3 );
  140.    
  141.     printf("郵便番号:");                    scanf( "%s" , ( pointer + user )->zip_code );
  142.     printf("住所:");                      scanf( "%s" , ( pointer + user )->address );
  143.    
  144.     printf("グループ(学校とか会社とか):");  scanf( "%s" , ( pointer + user )->group );
  145.    
  146.     printf("--------------------------------\n");
  147.    
  148.     return 1;
  149. }
  150.  
  151. /*受け取った構造体配列のポインタに格納されているユーザーデータを全項目について表示
  152. 返す値については未定とする*/
  153. void DispUserDatail( struct userdata *pointer )
  154. {
  155.     int user_number;
  156.    
  157.     printf("指定された個人の詳細を表示します\n");
  158.     printf("No:");
  159.     scanf("%d" , &user_number );
  160.    
  161.     //配列の添え字は0から始まるが表示は1からなのでデクリメント
  162.     user_number--;
  163.    
  164.     printf("\n--------------------------------\n");
  165.    
  166.     printf( "%s" ,   ( pointer + user_number )->last_name );
  167.     printf( "%s\n" , ( pointer + user_number )->first_name );   //姓名表示
  168.    
  169.     printf( "%s" ,   ( pointer + user_number )->last_name_phonetic );
  170.     printf( "%s\n" , ( pointer + user_number )->first_name_phonetic );  //姓名ふりがな表示
  171.    
  172.     printf("電話番号1:%s\n" , ( pointer + user_number )->phone_number1 );       //電話番号1
  173.     printf("電話番号2:%s\n" , ( pointer + user_number )->phone_number2 );       //電話番号2
  174.     printf("電話番号3:%s\n" , ( pointer + user_number )->phone_number3 );       //電話番号3
  175.    
  176.     printf( "メールアドレス1:%s\n" , ( pointer + user_number )->mail_address1 ); //メールアドレス1
  177.     printf( "メールアドレス2:%s\n" , ( pointer + user_number )->mail_address2 ); //メールアドレス2
  178.     printf( "メールアドレス3:%s\n" , ( pointer + user_number )->mail_address3 ); //メールアドレス3
  179.    
  180.     printf( "郵便番号:%s\n" , ( pointer + user_number )->zip_code );        //郵便番号
  181.     printf( "住所:%s\n" , ( pointer + user_number )->address );               //住所
  182.    
  183.     printf("グループ:%s\n" , ( pointer + user_number )->group );        //グループ
  184.    
  185.     printf("--------------------------------\n\n");
  186. }
  187.  
  188. /*ReadUserDataでtxtファイルから読み込んだ文字列の改行を削除する
  189. 引数として構造体配列の操作する配列のポインタを受け取る。*/
  190. void DeleteNewLine( struct userdata *pointer )
  191. {
  192.     //ポインタとして格納する配列名は"pointer"である必要がある
  193.     //DELETE_CLはdefinrマクロにて定義済み
  194.     DELETE_CL( first_name );                //名
  195.     DELETE_CL( last_name );                 //姓
  196.     DELETE_CL( first_name_phonetic );       //名ふりがな
  197.     DELETE_CL( last_name_phonetic );        //姓ふりがな
  198.     DELETE_CL( phone_number1 );             //電話番号1
  199.     DELETE_CL( phone_number2 );             //電話番号2
  200.     DELETE_CL( phone_number3 );             //電話番号3
  201.     DELETE_CL( mail_address1 );             //メールアドレス1
  202.     DELETE_CL( mail_address2 );             //メールアドレス2
  203.     DELETE_CL( mail_address3 );             //メールアドレス3
  204.     DELETE_CL( zip_code );                  //郵便番号
  205.     DELETE_CL( address );                   //住所
  206.     DELETE_CL( group );                     //グループ
  207. }
  208.  
  209. int Menu( struct userdata *pointer , int user , int *user_p )
  210. {
  211.     int select_menu;
  212.     int written_users;
  213.    
  214.     printf("何か入力してくださいな。\n");
  215.    
  216.     getch();
  217.     system( "cls" );
  218.     printf("1:電話帳表示\n");
  219.     printf("2:項目の詳細表示\n");
  220.     printf("3:新規登録\n");
  221.     //printf("4:検索\n");
  222.     printf("0:終了\n");
  223.    
  224.     //ハイパー入力された値のチェックターイム!!!!
  225.     do
  226.     {
  227.         //初期化
  228.         select_menu = -1;
  229.        
  230.         printf("動作:");
  231.         scanf( "%d" , &select_menu );
  232.        
  233.         if( select_menu < 0 || select_menu > 4 )
  234.         {
  235.             printf("無効な値です.\n再入力してください.\n");
  236.         }
  237.        
  238.         else;
  239.        
  240.     }while( select_menu < 0 || select_menu > 4 );
  241.    
  242.     switch( select_menu )
  243.     {
  244.         case 0:
  245.         {
  246.             //書き込み完了ユーザ数代入
  247.             written_users = WriteUserData2Txt( pointer , user );
  248.            
  249.             //ダイアログ表示
  250.             printf("%d人のデータを正常に書き込みました\n" , written_users );
  251.             printf("プログラムを終了します\n");
  252.             break;
  253.         }
  254.        
  255.         case 1:
  256.         {
  257.             //電話帳(氏名のみ)表示
  258.             DispData( pointer , user );
  259.             break;
  260.         }
  261.        
  262.         case 2:
  263.         {
  264.             //指定されたユーザの詳細表示
  265.             DispUserDatail( pointer );
  266.             break;
  267.         }
  268.         case 3:
  269.         {
  270.             //電話帳に書き込むのよ(ユーザ数の追加)
  271.             *user_p += AddNewUser( pointer , user );
  272.             break ;
  273.         }
  274.     }
  275.    
  276.     return select_menu;
  277. }
  278.  
  279. /*これ「2012-02-22 0時32分にここまで書いた」とか書いたほうがいいんだろうけどそんな順序良く書いてるわけじゃないから
  280. 結局やらないんだよね……^^;*/
  281.  
  282. /*txtファイルの有無をチェックする。fopen関数において、読み取りモードでエラーが発生した場合、
  283. 新しくtxtファイルを作成する。データは初期化される。(txtファイルの先頭に「end」を書き込む)
  284. txtファイルが存在する場合は1を、何らかのエラーの場合は0を返す*/
  285. int CheckTxtFile( void )
  286. {
  287.     FILE *file_p;       //ファイルポインタ
  288.    
  289.     int file_flag = 0;  //ファイル存在フラグ
  290.    
  291.     //file_flagが0の場合ループ
  292.     while( !file_flag )
  293.     {
  294.         file_p = fopen( FILE_NAME , "r" );
  295.        
  296.         //ファイルが存在しない、もしくはfopenに失敗した場合
  297.         if( file_p == NULL )
  298.         {
  299.             //書きこみモードでtxtファイルを新規作成
  300.             file_p = fopen( FILE_NAME , "w" );
  301.            
  302.             //fprintf( file_p , "start" );
  303.            
  304.             //ファイルのクローズ
  305.             fclose( file_p );
  306.            
  307.             //フラグを立てる
  308.             file_flag = 1;
  309.         }
  310.        
  311.         //ファイルが存在する場合
  312.         else
  313.         {
  314.             //ファイルのクローズ
  315.             fclose( file_p );
  316.            
  317.             //フラグを立てる
  318.             file_flag = 1;
  319.         }
  320.     }
  321.    
  322.     //値の返却
  323.     return file_flag;
  324. }
  325.  
  326. /*電話帳に登録されているデータを表示。表示するのは氏名のみ。
  327. 引数として、構造体配列の先頭アドレス、登録人数を受け取る。*/
  328. void DispData( struct userdata *pointer , int user )
  329. {
  330.     int num;
  331.    
  332.     printf("\n--------------------------------\n");
  333.    
  334.     //登録されている人数分繰り返す
  335.     for( num = 0; num < user; num++ )
  336.     {
  337.         //表示例「 12:中村 勇介」
  338.         printf("%3d:%s %s\n" , num + 1 , ( pointer + num )->last_name , ( pointer + num )->first_name );
  339.     }
  340.    
  341.     printf("--------------------------------\n\n");
  342. }
  343.  
  344. /*txtファイルから構造体にデータを格納する。
  345. 引数として構造体配列の先頭アドレスを受け取る。登録人数を返す*/
  346. int ReadUserData( struct userdata *pointer )
  347. {
  348.     //ファイルポインタ格納変数
  349.     FILE *file_p;
  350.    
  351.     int num;
  352.    
  353.     char tmp = 1;
  354.    
  355.     printf("電話帳データロード中\n");
  356.    
  357.     //ファイルオープン
  358.     if ( ( file_p = fopen( FILE_NAME , "r" ) ) == NULL )
  359.     {
  360.         //エラーメッセージ出力
  361.         printf( ERROR_FILE );
  362.        
  363.         //強制終了
  364.         exit( EXIT_FAILURE );
  365.     }
  366.    
  367.     else;
  368.    
  369.     //構造体の各メンバにデータを代入
  370.     //EOF行読み込みで終了(for文内if文で処理)
  371.     for( num = 0; ; num++ )
  372.     {
  373.        
  374.         tmp = fgetc( file_p );
  375.        
  376.         if( tmp == EOF )
  377.         {
  378.             break;
  379.         }
  380.        
  381.         else;
  382.        
  383.         //情報を構造体のメンバに読み込む
  384.         fgets( ( pointer + num )->first_name , 256 , file_p );              //名
  385.         fgets( ( pointer + num )->last_name , 256 , file_p );               //姓
  386.        
  387.         fgets( ( pointer + num )->first_name_phonetic , 256 , file_p );     //名フリガナ
  388.         fgets( ( pointer + num )->last_name_phonetic , 256 , file_p );      //姓フリガナ
  389.        
  390.         fgets( ( pointer + num )->phone_number1 , 256 , file_p );           //電話番号1
  391.         fgets( ( pointer + num )->phone_number2 , 256 , file_p );           //電話番号2
  392.         fgets( ( pointer + num )->phone_number3 , 256 , file_p );           //電話番号3
  393.        
  394.         fgets( ( pointer + num )->mail_address1 , 256 , file_p );           //メールアドレス1
  395.         fgets( ( pointer + num )->mail_address2 , 256 , file_p );           //メールアドレス2
  396.         fgets( ( pointer + num )->mail_address3 , 256 , file_p );           //メールアドレス3
  397.        
  398.         fgets( ( pointer + num )->zip_code , 256 , file_p );                //郵便番号
  399.         fgets( ( pointer + num )->address , 256 , file_p );                 //住所
  400.        
  401.         fgets( ( pointer + num )->group , 256 , file_p );                   //グループ
  402.        
  403.         //改行の削除
  404.         DeleteNewLine( pointer + num );
  405.        
  406.     }
  407.    
  408.     //ファイルを閉じる
  409.     fclose( file_p );
  410.    
  411.     printf("%d人のデータをロードしました\n" , num );
  412.    
  413.     //読み込み人数を返す
  414.     return num;
  415. }
  416.  
  417. int main( void )
  418. {
  419.     //友達(NUMBER_OF_USERS)人できるかな
  420.     struct userdata data_array[NUMBER_OF_USERS];
  421.    
  422.     int users;  //テキストファイル中に記述されているユーザー数格納
  423.    
  424.     //ファイルがエラーの場合
  425.     if( !CheckTxtFile() )
  426.     {
  427.         //エラーメッセージ出力
  428.         printf( ERROR_FILE );
  429.        
  430.         //強制終了
  431.         exit( EXIT_FAILURE );
  432.     }
  433.     else;
  434.    
  435.     //ユーザーデータ格納
  436.     users = ReadUserData( data_array );
  437.    
  438.     do{
  439.         printf("%d人のデータが読み込まれています\n" , users );
  440.        
  441.     }while( Menu( data_array , users , &users ) );
  442.    
  443.     return 0;
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement