名簿から頭文字で範囲検索するプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ririri

名簿から頭文字で範囲検索するプログラム

#1

投稿記事 by ririri » 11年前

課題で名簿から頭文字で範囲検索をするプログラムが出題されました。
ローマ字名、ローマ字名の漢字名、住所、電話番号(ここはカンタンでいい)の四行の中のローマ字の頭文字を判定して、辞書のように頭文字で範囲検索するプログラムなんですが・・・。
名簿には

aoki
青木
東京
03-29
takagi
高木
神奈川
09-81
doi
土井
石川
87-8

のようなテキストファイルを用意し、このアルファベットの一番上を判定するものだと思ってプログラムを書きました。
でもうまくいかず・・・。
今のことろここまでできています。

コード:

 
#include<stdio.h>
#include<string.h>
main()
{FILE *fp;
 int i,k,n;
 struct{
 char name[100],shimei[100],jusho[100],f[100],e[100],tel;
 }data[100];
 char fname[80];
 printf("ファイル名\n");
 scanf("%s",&fname);
 fp=fopen(fname,"r");
 i=1;
 while(fscanf(fp,"%s",&data[i].name)!=EOF){
       fscanf(fp,"%s",&data[i].shimei);
       fscanf(fp,"%s",&data[i].jusho);
       fscanf(fp,"%s",&data[i].tel);
       i=i+1;
       } 
 printf("検索範囲\n");
 printf("始まり="); 
 scanf("%s",data[i].f);
 printf("終わり="); 
 scanf("%s",data[i].e);
 k=0;
 for(i=1;i<=5;i++){
 if(strcmp(data[i].name,data[i].f)&&(data[i].name<data[i].e)==0){
    printf("ローマ字名%s\n",data[i].name);
    printf("氏名%s\n",data[i].shimei);
    printf("住所%s\n",data[i].jusho);
    printf("電話番号%s\n",data[i].tel);
    k=k+1;
    }}
 if(k==0){printf("該当者いない\n");}
 
 fclose(fp);
 }
 

アバター
usao
記事: 1892
登録日時: 12年前
連絡を取る:

Re: 名簿から頭文字で範囲検索するプログラム

#2

投稿記事 by usao » 11年前

>ローマ字の頭文字を判定して、辞書のように頭文字で範囲検索する

これ,もうちょっとわかりやすく説明できませんか?
どのような入力を行ったらどうのような結果が出てくることになるのでしょうか?
関連して,28行目のif文はどういった判定を行っているのでしょうか.
(あと,27行目のforが i=1~5 という固定範囲を対象にしているのも不自然に感じます.)


7~9行目の構造体のメンバについて,
・name[100] が ローマ字名用
・shimei[100] が 漢字名用
・jusho[100] が住所用
なのだと思いますが,
e[100]とf[100]は何のための物なのでしょう?
また,telは電話番号用なのだと思いますが,その宣言で大丈夫ですか?(18行目の使い方に合っていないと思います)

ririri

Re: 名簿から頭文字で範囲検索するプログラム

#3

投稿記事 by ririri » 11年前

アルファベットを一文字ずつ入力して、その範囲で検索する・・・というものです。
例えば、
始まり=d
終わり=s
と入力したらd〜sからはじまるローマ字名の人物の情報が並べてでてくる、といった感じです。
fは始まりで入力した文字らeは終わりに入力した文字に対応させるつもりでした。
でも、自分のやり方が間違っているのかうまく動かないので別のやり方をするべきなんでしょうね。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 名簿から頭文字で範囲検索するプログラム

#4

投稿記事 by みけCAT » 11年前

ririri さんが書きました:

コード:

if(strcmp(data[i].name,data[i].f)&&(data[i].name<data[i].e)==0){
この部分の条件文がわかりにくいですね。
とりあえず二重否定を消して

コード:

if(strcmp(data[i].name, data[i].f) != 0 && data[i].name>=data[i].e){
配列の先頭要素のポインタを比較しても意味が無さそうなので、
なぜか前半のみで用いられているstrcmpを後半でも用いて

コード:

if(strcmp(data[i].name, data[i].f) != 0 && strcmp(data[i].name, data[i].e) >= 0){
条件がおかしい気がするので適切に修正してみました。

コード:

if(strncmp(data[i].f, data[i].name, 1) <= 0 && strncmp(data[i].name, data[i].e, 1) <= 0){
さらに、ほかの部分も修正してみました。
  • main関数の型を適切に修正した
  • ファイルが開けたかのチェックを追加した
  • main関数がきちんと戻り値を返すようにした
  • telをchar型からchar[100]型にした
  • scanfとfscanfで用いられている余計な&を消した
  • f,eを構造体のメンバではなく、普通のローカル変数にした
  • 使用されていない変数nを消した

コード:

#include<stdio.h>
#include<string.h>
int main(void)
{FILE *fp;
 int i,k;
 struct{
 char name[100],shimei[100],jusho[100],tel[100];
 }data[100];
 char f[100],e[100];
 char fname[80];
 printf("ファイル名\n");
 scanf("%s",fname);
 fp=fopen(fname,"r");
 if(fp==NULL){puts("file open error");return 1;}
 i=1;
 while(fscanf(fp,"%s",data[i].name)!=EOF){
       fscanf(fp,"%s",data[i].shimei);
       fscanf(fp,"%s",data[i].jusho);
       fscanf(fp,"%s",data[i].tel);
       i=i+1;
       } 
 printf("検索範囲\n");
 printf("始まり=");
 scanf("%s",f);
 printf("終わり=");
 scanf("%s",e);
 k=0;
 for(i=1;i<=5;i++){
 if(strncmp(f,data[i].name,1)<=0&&strncmp(data[i].name,e,1)<=0){
    printf("ローマ字名%s\n",data[i].name);
    printf("氏名%s\n",data[i].shimei);
    printf("住所%s\n",data[i].jusho);
    printf("電話番号%s\n",data[i].tel);
    k=k+1;
    }}
 if(k==0){printf("該当者いない\n");}
 
 fclose(fp);
 return 0;
 }
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ririri

Re: 名簿から頭文字で範囲検索するプログラム

#5

投稿記事 by ririri » 11年前

mainの関数なんですが、これをなんとか
main()の状態で作れないでしょうか?
voidという関数は扱っていなくてつかってはいけないようなので・・・。

条件の指定はなるほどと納得できました。
こうすればうまく動くんですね。

ririri

Re: 名簿から頭文字で範囲検索するプログラム

#6

投稿記事 by ririri » 11年前

5については解決しました。
ありがとうございました。
うまくできそうです。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 名簿から頭文字で範囲検索するプログラム

#7

投稿記事 by みけCAT » 11年前

ririri さんが書きました:mainの関数なんですが、これをなんとか
main()の状態で作れないでしょうか?
voidという関数は扱っていなくてつかってはいけないようなので・・・。
「voidという関数」は使っていません。
C++ならint main()と書いてもいいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: 名簿から頭文字で範囲検索するプログラム

#8

投稿記事 by かずま » 11年前

ririri さんが書きました: 条件の指定はなるほどと納得できました。
こうすればうまく動くんですね。
1文字の比較に strcmp を使う必要はありません。

コード:

#include <stdio.h>

int main()
{
    FILE *fp;
    char fname[80], name[100], shimei[100], jusho[100], tel[100], f, e;
    int k = 0;

    printf("ファイル名\n"), scanf("%79s", fname);
    fp = fopen(fname, "r");
    if (!fp) return 1;

    printf("検索範囲\n" "始まり="), scanf(" %c", &f);
    printf("終わり="), scanf(" %c", &e);

    while (fscanf(fp,"%99s%99s%99s%99s", name, shimei, jusho, tel) == 4)
        if (name[0] >= f && name[0] <= e)
            printf("ローマ字名: %s\n氏名: %s\n住所: %s\n電話番号: %s\n",
                name, shimei, jusho, tel), k++;

    if (k == 0) puts("該当者いない");
    fclose(fp);
    return 0;
}
構造体の配列も不要です。

閉鎖

“C言語何でも質問掲示板” へ戻る