C言語でCSVファイルを読み取りたい、でも失敗する・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Jimmy
記事: 9
登録日時: 7年前

C言語でCSVファイルを読み取りたい、でも失敗する・・・

#1

投稿記事 by Jimmy » 7年前

test.csv
[tab=30]late,遅れた
[tab=30]latest,最新の
[tab=30]current,現在通用している

上記のデータを用いて以下のプログラムを実行するとうまくいきません。

コード:

#include<stdio.h>
#define MAX_WORDS 3

int main()
{
	FILE *fp;
	char words[MAX_WORDS][10], meaning[MAX_WORDS][10];
	int i;

	if((fp=fopen("test.csv","r"))==NULL){
		printf("ファイルがありません\n");
		return 1;
	}

	for(i=0; i<MAX_WORDS; i++){
		fscanf(fp,"%[^,],%[^,]",words[i], meaning[i]);
	}

	for(i=0; i<MAX_WORDS; i++){
		printf("%s %s\n",words[i], meaning[i]);
	}
	fclose(fp);
	getchar();
	return 0;

}
出力結果が以下のように文字化けします。
wordsやmeaning配列に格納される文字列も意図したものではないのだと思います。
late 遅れた
latest
フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ01フフフフハainク est
フフフフフフフフフフフフフフフフフフフフ01フフフフハainク フフフフフフフフフフフフフフフフフフフフlate

ですが、以下のように編集を加えると、ある程度うまくいきます。
test.csv
[tab=30]late,遅れた,
[tab=30]latest,最新の,
[tab=30]current,現在通用している,
各行の終わりにコンマを入れました。

↓ソースコードの16行目にコンマを追加しました。

コード:

#include<stdio.h>
#define MAX_WORDS 3

int main()
{
	FILE *fp;
	char words[MAX_WORDS][10], meaning[MAX_WORDS][10];
	int i;

	if((fp=fopen("test.csv","r"))==NULL){
		printf("ファイルがありません\n");
		return 1;
	}

	for(i=0; i<MAX_WORDS; i++){
		fscanf(fp,"%[^,],%[^,],",words[i], meaning[i]);
	}

	for(i=0; i<MAX_WORDS; i++){
		printf("%s %s\n",words[i], meaning[i]);
	}
	fclose(fp);
	getchar();
	return 0;

}
出力結果は以下のようになりました。
late 遅れた

latest 最新の

current 現在通用している
ですが、20行目のprintf("%s %s\n",words, meaning);で1回しか改行していないはずなのに、なぜか2回改行されています。
多分meaning[]配列が\nも含んでしまっているのだと思います。(含まないようにしたいです)
目標は、
late 遅れた
latest 最新の
current 現在通用している
のように表示させることです。

あとtest.txtの各行の終わりにコンマを加えずに、この目標を達成したいです。
お願いします!
最後に編集したユーザー Jimmy on 2013年3月18日(月) 19:48 [ 編集 1 回目 ]

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

Re: C言語でCSVファイルを読み取りたい、でも失敗する・・・

#2

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

「現在通用している」は10バイトを超えるので、配列の範囲外を参照して危険です。
fgetsで1行ずつ読み込み、strchrなどで改行を消してからstrtokで分割してコピーするのがいいと思います。
sscanfで現状のscanfのようにする方が簡単です。

コード:

#include <stdio.h>
#include <string.h>
#define MAX_WORDS 3

int main()
{
    FILE *fp;
    char words[MAX_WORDS][128], meaning[MAX_WORDS][128];
    int i;

    if((fp=fopen("test.csv","r"))==NULL){
        printf("ファイルがありません\n");
        return 1;
    }
 
    for(i=0; i<MAX_WORDS; i++){
        char buffer[1024];
        char* newLine;
        fgets(buffer,sizeof(buffer),fp);
        if(newLine=strchr(buffer,'\n'))*newLine=0;
        sscanf(buffer,"%[^,],%[^,]",words[i], meaning[i]);
    }
 
    for(i=0; i<MAX_WORDS; i++){
        printf("%s %s\n",words[i], meaning[i]);
    }
    fclose(fp);
    getchar();
    return 0;
 
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Jimmy
記事: 9
登録日時: 7年前

Re: C言語でCSVファイルを読み取りたい、でも失敗する・・・

#3

投稿記事 by Jimmy » 7年前

みけCATさんありがとうございます!

>「現在通用している」は10バイトを超えるので、配列の範囲外を参照して危険です。
分かりました。以後、気をつけます。(でも、どうしてエラー出なかったんだろ(独り言))

>fgetsで1行ずつ読み込み、strchrなどで改行を消してからstrtokで分割してコピーするのがいいと思います。
この方法で組んでみたいと思います。
CSVを読み取るときはこの方法が一番スマートなのですか?
fscanf()でうまく対応する方法はありますか?
良ければ教えて下さい。

Jimmy
記事: 9
登録日時: 7年前

Re: C言語でCSVファイルを読み取りたい、でも失敗する・・・

#4

投稿記事 by Jimmy » 7年前

タイプが遅くて、編集前のみけCATさんの内容に返信してしまいました。

Jimmy
記事: 9
登録日時: 7年前

Re: C言語でCSVファイルを読み取りたい、でも失敗する・・・

#5

投稿記事 by Jimmy » 7年前

みけCATさんのプログラムを理解するのに、時間がかかり過ぎました(汗

strchrは使ったことがなかったので、参考になりました。
17、18行目のように変数の宣言を繰り返しの中に入れても問題ないんですね。初めて知りました。

sscanfも便利な関数ぽいので、覚えておきます。
お世話になりました!

Jimmy
記事: 9
登録日時: 7年前

Re: C言語でCSVファイルを読み取りたい、でも失敗する・・・

#6

投稿記事 by Jimmy » 7年前

クイック送信では、解決のクリックがなかったんですね。
解決したのでこちらを使って解決チェックします。

ありがとうございました!

閉鎖

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