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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

Q&A

解決済

1回答

9023閲覧

C言語を用いて読み込んだファイルを線形リストにし表示したい

KEILA

総合スコア15

C

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

0グッド

0クリップ

投稿2017/07/12 08:19

編集2017/07/12 08:49

以下のようなデータテキストを

10 香川真司 FW_1989/03/17 17 長谷部誠 MF_1984/01/18 5 長友佑都 DF_1986/09/12 13 大久保嘉人 FW_1982/06/09 7 遠藤保仁 MF_1980/01/28 9 岡崎慎司 FW_1986/04/16 1 川島永嗣 GK_1983/03/20 4 本田圭佑 MF_1986/06/13 2 内田篤人 DF_1988/03/27 15 今野泰幸 DF_1983/01/25 22 吉田麻也 DF_1988/08/24

構造体に読み取り、標準画面出力しようと考えて下記のようなコードを書きました。(ただし、練習のため線形リストを使うようにしています)

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4 5/* 構造体の定義 */ 6struct member{ 7 int num; /* 登録番号 */ 8 char name[13]; /* 氏名 */ 9 char profile[45]; /* プロフィール */ 10 struct member *next; 11}; 12 13typedef struct member list_mbr; 14 15list_mbr *list(FILE *fp); 16void printlist(list_mbr *p); 17 18int main(int argc,char* argv[]){ 19 FILE *fp; 20 list_mbr *listptr; 21 22 if ((fp = fopen("test.txt", "r"))==NULL) { 23 fprintf(stderr,"ファイルを開くのに失敗しました\n"); 24 exit(1); 25 } 26 listptr = list(fp); 27 printlist(listptr); 28 fclose(fp); 29 return 0; 30} 31 32 33 34/* list()関数:ファイルポインタを引数とし、ファイルから */ 35/* データを読み込みリストを作成する。 */ 36/* 戻り値は、作成されたリストの先頭データのアドレス */ 37list_mbr *list(FILE *fp){ 38 int d; 39 list_mbr *p,*newp; 40 41 p=NULL; 42 while(fscanf(fp,"%d %s %s\n",&p->num,p->name,p->profile) != EOF){ 43 newp->next = p; 44 p = newp; 45 } 46 return p; 47} 48 49 50/* printlist()関数:リストの先頭データのアドレスを引数 */ 51/* とし、リストの内容を出力する */ 52void printlist(list_mbr *p){ 53 while (p != NULL) { 54 printf("%d %s %s ", p->num,p->name,p->profile); 55 p = p->next; 56 } 57 printf("\n"); 58}

このコードを実行しようとしたものの、うまくいかず(実行時に「セグメンテーション違反です (コアダンプ)」とエラーが出て強制終了します。おそらくlist()関数内部のデータの読み取り部分で上手く読み取れていないと思われます)困っています。どのように直せばいいでしょうか。

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

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

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

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

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

guest

回答1

0

ベストアンサー

リスト構造を扱いたいのですね、結論から言えばヒープ領域スコープという概念を調べてみてください。
おそらくポインタの概念も怪しいですね。

なぜ、セグメンテーション違反が起きているかというと、未定義(未初期化)のポインタに値を書き込んでいるからです。
list_mbr *pはポインタではなく、list_mbr pと実体を定義すべきですね。

数行直すだけで動くコードではなかったので、問題がある部分の指摘だけで失礼します。

投稿2017/07/12 10:08

pashango2

総合スコア930

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

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

KEILA

2017/07/13 05:31

回答ありがとうございます。 たしかに基礎的なことの理解が不十分だったようで、ポインタから再度勉強し直すことにしました。
KEILA

2017/07/13 05:35

回答いただいたとおり、メモリを確保するように以下のように書き換えたところ無事動作しました。 ```C list_mbr *list(FILE *fp){ list_mbr *p,*newp; p=NULL; newp = (list_mbr *)malloc(sizeof(list_mbr)); while(fscanf(fp,"%d %s %s",&newp->num,newp->name,newp->profile) != EOF){ newp->next = p; p = newp; newp = (list_mbr *)malloc(sizeof(list_mbr)); } return p; } ``` ありがとうございました。
pashango2

2017/07/13 05:50 編集

コードを見る限り上手く動くようには見えません。 戻り値のpは先頭ポインタを返すべきですが、実際には最後から2番めのポインタを返しています。 最初のmalloc関数の部分をこうすべきでは? list_mbr *startp; startp = newp = (list_mbr *)malloc(sizeof(list_mbr)); returnはstartpを返す。 return startp;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問