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

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

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

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Q&A

0回答

572閲覧

[c言語]csvファイルからのからのデータを構造体に保存し、操作を加えた後テキストファイルに保存するプログラムについて

soft_cream

総合スコア11

C

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

0グッド

0クリップ

投稿2021/06/21 04:57

編集2021/06/21 05:06

前提・実現したいこと

[c言語]csvファイルにカンマ区切りで保存されたデータ(id、氏名、点数)を構造体に保存し、キーボードから入力された閾値:threshold以上の点数を持つ氏名を表示、またテキストファイルに書き込むプログラムを作成したいです。コンパイルは通ったのですが、実行の際に以下のようなエラーが表示されました。

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

Error
Segmentation fault (core dumped)

該当のソースコード

//以下の3つのファイルに分けています //プロトタイプ宣言や構造体の定義を行うヘッダーファイルstructure.h struct student{ char ID[9]; char name[33]; int score; }; int read_csv(char input_data[49][50]); void init(char input_data[49][50],char set_i[49][9],char set_n[49][33],int set_sc[49],int fin); void co_cont(struct student*,char); void more(struct student*,int,int); //メイン関数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include"structure.h" #include"operation.c" int main(void){ int count=0,threshold; char yn; struct student *ptr; char stu_data[49][50],stu_id[49][9],stu_name[49][33]; int stu_score[49]; count = read_csv(stu_data); ptr = (struct student*)malloc(sizeof(struct student)*count); init(stu_data,stu_id,stu_name,stu_score,count); cp_cont(ptr,stu_id,stu_name,stu_score); while(1){ printf("threshold? > "); scanf("%d",&threshold); more(ptr,threshold,count); printf("end? y/n"); scanf("%c",&yn); if(yn=='y'){ break; } } return 0; } //メイン関数以外の関数を記述したファイルoperation.c int read_csv(char input_data[49][50]){ FILE *fp; int l,d; l = 0; d = 0; fp = fopen("students.csv","r"); if(fp == NULL){ printf("Error\n"); return -1; } while(fgets(input_data[l],50,fp) != NULL){ printf("test1%s\n",input_data[l]); l++; } fclose(fp); return l; } void init(char input_data[49][50],char set_i[49][9],char set_n[49][33],int set_sc[49],int fin){ int i,j,c,t; char con[10]; i = 0; j = 0; t = 0; while(fin != 0){ while(input_data[j][i] != ','){ set_i[j][t] = input_data[j][i]; i++; t++; } i++; set_i[j][t] = '\0'; t= 0; while(input_data[j][i] != ','){ set_n[j][t] = input_data[j][i]; i++; t++; } i++; set_n[j][t] = '\0'; t = 0; while(input_data[j][i] != '\0'){ con[t] = input_data[j][i]; i++; t++; } set_sc[j] = atoi(con); con[0] = '\0'; fin--; j++; i = 0; t = 0; } } void cp_cont(struct student *detail,char id[49][9],char nam[49][33],int sc[49]){ int i,j,c; j = 0; c = 49; detail = NULL; while(c != 0){ strcpy((detail+j)->ID,id[j]); printf("%s ",(detail+j)->ID); strcpy((detail+j)->name,nam[j]); printf("%s ",(detail+j)->name); (detail+j)->score = sc[j]; printf("%d\n",(detail+j)->score); j++; c--; } } void more(struct student *ptr , int threshold , int count){ int i=0; FILE *fp; char filename[50]; printf("file name ? > "); fgets(filename,30,stdin); fp = fopen("filename.txt","w"); while(count != 0){ if(ptr->score >= threshold){ printf("%s\n",(ptr+i)->name); fprintf(fp,"%s,%s,%d\n",(ptr+i)->ID,(ptr+i)->name,(ptr+i)->score); } i++; count--; } }

試したこと

ファイルオープンに失敗しているのでは、とアドバイスをもらい
ファイルオープンから構造体への保存までを教えていただいたプログラムで試しましたが
同じエラーが出てしまいました。

他にどのような問題点が考えられるでしょうか?
自分の実行環境に何か問題があるのでしょうか?
回答してくれる人の中で自分のソースコードで実行出来る方はいませんか?

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

Ubuntuを使用してプログラムを書いています。読み込むためのcsvファイルはデスクトップに置いています。
ごめんなさい、このサイトを使うのは初めてでして、使い方もまだよく分かっていませんでした。codeボタンのことを教えていただきありがとうこざいます。

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

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

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

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

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

y_waiwai

2021/06/21 05:00

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
soft_cream

2021/06/21 05:10

ご指摘ありがとうございます。修正させていただきました。 このサイトを使うのが初めてで、まだよくわかっていませんでした。申し訳ございません。 これで大丈夫でしょうか?
littlestream

2021/06/21 08:12 編集

students.csvファイルは既に存在しているのでしょうか?それともまだ書き込めていないなら errorのprintfの出力が出てもおかしくないと思います。
littlestream

2021/06/21 08:38 編集

1,suzuki,30 2,ozawa,60 3,tanaka,45 5,nishikawa,22 8,ushijima,69 とりあえず、このすぐ上のテキストデータをstudents.csvファイルに保存してみてはいかがでしょうか。 そうすれば少なくともこちらの環境でコンパイルして実行したらファイルエラーはなくなりました。 環境はWindows10,32bit,BorlandC++Compilerです
soft_cream

2021/06/21 09:50

student.csvファイル自体はあります プログラムの実行ファイルと同じフォルダに csvファイルを置きたいのですが 実行ファイルの場所が分からず デスクトップにcsvファイルを置いている状態です やっぱり同じ場所に置かないとダメですよね? 実行ファイルの場所の調べ方などがありますか? また ファイルエラーはなくなった ということは 他の操作はまだおかしい点がある ということでしょうか?
BeatStar

2021/06/21 10:07

UbuntuはOSです。 開発環境(IDE)かコンパイラの名前が必要です。 VC++とかの場合と、MinGWとかのようなコンパイラのみだとファイル・ディレクトリ構造が違うので。
littlestream

2021/06/21 10:19 編集

その実行ファイルのディレクトリというかフォルダの位置 を調べるならちょっとソースをc言語とWINAPIで示したいのですが、 自分は長年Windowsしか開発環境による依存をしていないため、soft_creamさんの開発環境 がubuntsuだという事を考えると、WINAPIを使えないのが残念です。ただし、cには system("dir");とかsystem("$ cd ./");という関数で実行中のディレクトリの 大体の位置が分かると思います。うまくいくと良いです。
soft_cream

2021/06/21 11:05

コンパイラの名前とはgccコンパイラでいいのでしょうか?
BeatStar

2021/06/21 11:09

>> コンパイラの名前とはgccコンパイラでいいのでしょうか OKです。たとえばMinGWを別途インストールしているのなら『MinGW gcc』とかみたいに書いてください。(できればバージョンも) UNIXとかだと、すでにgccが元から入っているようなので、そういう場合は『gcc』でいいです。 (できればバージョンも)
BeatStar

2021/06/21 11:12

また、セグフォ( Segmentation Fault ) は主に、『あり得ない場所にアクセスしている』とかが多いです。 (もしかしたら『ファイルが無い』とかのようなものもか?) こういう場合はデバッガ ( MinGW でいえば GDB 、VC++だと内蔵のヤツ ) で潜って調べるのです。 これをデバッグといいます。 まずはご自分でデバッグしてみましょう。 もしかしたらそれでわかるかもしれません。 それでもわからない場合は、もうちょっと質問方法を工夫して聞きましょう。 (他人が読んで、すぐに再現できるような説明が好ましい)
soft_cream

2021/06/21 12:21

バージョンは 2004.2021.222.0 で良いのでしょうか? すみません、実は今日の0時までに完成させないといけなくて 本当に勝手すぎるのですが デバックしてはいただけないでしょうか
BeatStar

2021/06/21 12:26

『デバッグしてくれ』は不適切です。 それは「課題丸投げ」と同じです。 そもそもプログラミングは「書いて終わり」じゃないです。 デバッグやテストまで含みます。 そして、そのデバッグも一括処理程度ですら1~2日は使います。 それを自分はやらずに、『他人がやるのが当たり前』っていう発想は正しいのでしょうか。 あまりにも身勝手すぎます。
BeatStar

2021/06/21 12:31 編集

今日の0時までであっても、今現在は22時。 少なくとも1時間はある。 まずは自分でできるところまではやりましょう。 ここであーだこーだ言う時間をデバッグに使う方が建設的では? もちろん、デバッグやってもどうしてもわからないならヒントぐらいは上げると思いますが。
soft_cream

2021/06/21 12:41

そうですよね、すみません。 やってみます。 まずはcsvファイルを実行ファイルと同じ場所に置こうと思うのですが 自分の書いたバージョンの説明は不十分でしょうか?
BeatStar

2021/06/21 13:03

えーっと、gccの場合、生成される実行ファイルはカレントディレクトリにあり、 VC++等の場合は独自の場所にあります。 なのでそこまで必要はないと思いますが、書いておいた方が無難かもしれません。
littlestream

2021/06/21 13:10

自分もc言語の超超初心者だったときは何が何だか分からなかったので気持ちはわかります。 今でも自分は超初心者なんですが。 で、逆転の発想です。デスクトップにcsvがあるならソースプログラムのフォルダ内に入れるのではなく csvファイルのあるデスクトップにソースをコピーペーストすればよいのではないでしょうか?
soft_cream

2021/06/21 13:11

カレントディレクトリにcsvファイルを移動させる方法などはないでしょうか
soft_cream

2021/06/21 13:15

littlestreamさん なるほど、やってみます
soft_cream

2021/06/21 13:19

メモ帳にソースコードをコピーし ファイル名.c や ファイル名.h などで保存すればよいでしょうか
soft_cream

2021/06/21 13:26 編集

littlestreamさんの環境で実行すると ファイルエラーはなくなったとお聞きしましたが 他にもおかしい部分があったのですか?
littlestream

2021/06/21 13:36

ちょっとおかしな点( char filename[50];なのに fgets(filename,30,stdin); fp=fopen("filename.txt",r);とか がありましたが自分のやり方で書くなら出来なくはないかもしれませんが、 個人的な意見というとCでポインタはあまり使いたくないです。 食わず嫌いもあるかもしれないですが C++なら参照とnew deleteが使えるので、 あと、もう一回、もともとのソースコードを写させてもらいます。
soft_cream

2021/06/21 13:44

50と30の問題はミスです。すみません。 filenameに関しては 繰り返し別の閾値で実行しようとした際に テキストファイルの名前が同じだといけないかなと思い ファイル名を指定できるようにしようとしたのですが このような書き方では 「filename」というファイルに何度も書き込むことになるのでしょうか?
soft_cream

2021/06/21 13:46

デスクトップにソースコードを保存した場合 ubuntu内で「cd」などによりデスクトップに移動する必要があるのでしょうか? その方法を教えていただけないでしょうか
soft_cream

2021/06/21 13:54

filemameの件については 一回ずつファイル名を指定するのをあきらめ、 代わりに閾値を書き込むことで 同じファイル内に書き込んでも区別できるようにすることにしました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問