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

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

ただいまの
回答率

88.91%

C言語でほかのファイルのデータを読み込みたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 874

Nicks11

score 5

前提・実現したいこと

C言語で他のファイルのメールアドレスを読み込み、共通するメールアドレスの一部をカウントすることを実現したいです。コマンドライン引数でファイルを指定する。

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

コアダンプ 

該当のソースコード

include <stdio.h>

include <stdlib.h>

include <string.h>

define email_SIZE 256

define buf_SIZE 256

define data_SIZE 512

/* メールアドレスとその登場回数を記録
するための構造体を定義 */
struct address {
char email[email_SIZE];
int count;
};

/*登録済みアドレスと一致していれば、登録済みアドレスのカウントを+1した後、0を返し
さもなくば、1を返す関数.*/
void check_new_address(int* n_address, struct address data[], char buf[]){
int i;
int is_new_address = 1;  /* 登録済みのアドレスかどうかを判定するためのフラグ */

for ( i = 0; i < (*n_address); i++ ){
if ( strcmp(data[i].email, buf) == 0 ){
data[i].count++;
is_new_address = 0;
break;
}
}

if ( is_new_address ){
i = (*n_address);
strcpy(data[i].email, buf);
data[i].count = 1;
(*n_address)++;
}
}

/* バブルソートのアルゴリズムで
登場回数の大きい順に data を並べ替える関数 */
void bubble_sort(int n, struct address data[]){
int i, j;

for ( i = 0; i < n; i++ ){
for ( j = 0; j < n-i-1; j++ ){
if ( data[j].count < data[j+1].count ){
struct address tmp;
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
}
}

/*出力形式を示す値を返す関数*/
int out_type_num(){
int ans;

printf("\n");
printf("登場回数の多い順に出力します.\n");
printf("出力形式を選んでください\n");
do{
printf(" 0: メールアドレス,登場回数の順に出力\n");
printf(" 1: 登場回数,メールアドレスの順に出力\n");
printf(" 2: メールアドレスのみを出力\n");
printf("> ");
scanf("%d", &ans);
}
while( ans < 0 || ans > 2 );

return ans;
}

void erase_line_feed(char buf[]){
int i;

while ( buf[i] != '\n' ){
i++;
}
buf[i] = '\0';   /*末尾の改行文字を\0に置き換える*/
}

int main(int argc, char *argv[]){
FILE* fp;                        /*ファイルポインタ変数*/
char buf[buf_SIZE];              /* データファイルから1行ずつ読み出して一時的に保存するための文字配列 */
struct address data[data_SIZE];  /* メールアドレスとその登場回数のデータ(構造体)の配列 */
int n_address;                   /* メールアドレスの種類数を記録 */
int i, n;                        /* i, j は配列の添字に使用,n はアドレスの総数を数えるために使用 */
int out_type;                    /* データ出力の形式を指定 */

/* データファイルをオープン */
printf("【データファイル】 %s\n", argv[1]);
fp = fopen(argv[1], "r");
if ( fp == NULL ){
printf("データファイルのオープンに失敗しました\n");
exit(1);
}

n = 0;
n_address = 0;
while ( fgets(buf, buf_SIZE, fp) != NULL ){
n++;

i = 0;
/*bufの末尾の改行文字を\0に書き換える関数*/
erase_line_feed(buf);

/* buf に格納されたアドレスが記録済みのものと一致しているかどうか確認 */
check_new_address(&n_address, data, buf);
}

printf("   %d 件のメールアドレスを読み込みました.\n", n);
fclose(fp);
printf("   全部で %d 種類のメールアドレスが見つかりました.\n", n_address);

/* dataをバブルソートで登場回数の多い順に並び替える */
bubble_sort(n_address, data);

/* 出力形式をユーザに問い合わせる */
out_type = out_type_num();

/* いずれかの形式で出力する */
if ( out_type == 0 ){
for ( i = 0; i < n_address; i++ ){
printf(" %s [%d 回]\n", data[i].email, data[i].count);
}
}
else if ( out_type == 1 ){
for ( i = 0; i < n_address; i++ ){
printf(" [%d 回] %s\n", data[i].count, data[i].email);
}
}
else{
for ( i = 0; i < n_address; i++ ){
printf(" %s\n", data[i].email);
}
}

return 0;
}

試したこと

ここに問題に対して試したことを記載してください。

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

別のファイル情報

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@xxx.biglobe.ne.jp

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@outlook.jp

xxx@outlook.jp

xxx@livedoor.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@outlook.jp

xxx@infoseek.jp

xxx@infoseek.jp

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@livedoor.com

xxx@infoseek.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@livedoor.com

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@outlook.jp

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@infoseek.jp

xxx@yahoo.co.jp

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@livedoor.com

xxx@outlook.jp

xxx@yahoo.co.jp

xxx@outlook.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@outlook.jp

xxx@excite.co.jp

xxx@gmail.com

xxx@outlook.jp

xxx@outlook.jp

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@infoseek.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@yahoo.co.jp

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@infoseek.jp

xxx@infoseek.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@infoseek.jp

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@yahoo.co.jp

xxx@gmail.com

xxx@yahoo.co.jp

xxx@outlook.jp

xxx@xxx.biglobe.ne.jp

xxx@gmail.com

xxx@gmail.com

xxx@gmail.com

xxx@xxx.biglobe.ne.jp

xxx@livedoor.com

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2020/07/13 21:35

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

0

コアダンプ  

とありますが、実際のエラーメッセージは全て載せないと原因は分からない事があります。また、デバッガ等を使えば、問題の発生個所も特定できますが、それはしてませんか?

なお、関数 void erase_line_feed(char buf[])の最初を int i = 0; (0で初期化) したら、それなりに結果が出ますが、、、? (コンパイルしたら、Warningが出た)
これが原因?


プログラムは、コードブロックに入れてください。確認が大変です。(一部の文字も消えるし、、) <code>アイコン(コードの挿入)でコードブロックが挿入されます。または、ヘルプ参照で。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る