C言語 CSV 格納

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

C言語 CSV 格納

#1

投稿記事 by こお » 9年前

始めて投稿させていただきます。
カンマ区切りのCSVからカンマまでの文字列を2次元配列にいれたくpの2次元配列を初期化して、その後ファイルを読み込み入れようと思ったのですが上手くいきません。
ヒントを頂けると嬉しいです。よろしくお願いします。
今は一文字ずつ読み込んで分岐処理でやろうと思っていましたが、一文字づつカウントアップしてしまいます。

コード:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>



int main(void) {
	int height = 11; //行数
	int(*p)[1400]; //要素数

	//行数×要素数のメモリを確保し、要素数が1400を1つの塊とした配列を11個用意している
	//メモリを要素数より多めにとらないとエラーがでる。
	p = (int (*)[1400])calloc(height * 1600, sizeof(int));

	if (p == NULL) 
		puts("領域の確保に失敗しました");
	else {
		int i, j;
		for (i = 0; i <= height; i++) 
			for (j = 0; j <= 1400; j++)
				p[i][j] = 0;

		/*for (i = 0; i <= height; i++)
			for (j = 0; j <= 1400; j++)
				printf("p[%d][%d] = %d\n", i, j, p[i][j]);*/
	
	}

	FILE *fp;
	int c,k,h;
	int column = 0;
	int row = 0;
	if ((fp = fopen("./file.csv", "r")) == NULL) {
		printf("ファイルをオープンできません");
		return(-1);
	}

	while ((c = fgetc(fp)) != EOF) {
		if (c == ',') {
			column++;
		}
		else if(c == '\n'){
			row++;
			column = 0;
		}
		else {
				p[row][column] = (char)c;
				printf("p[%d][%d] = %c\n", row,column,p[row][column]);
			}
		}
	fclose(fp);
	free(p);
	return(0);
}

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

Re: C言語 CSV 格納

#2

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

とりあえず、21行目で1400要素しかない配列pの範囲外の1400番目(0-origin)の要素に値を書き込んでいるので、未定義動作ですね。
1400のかわりに1600を掛けることでごまかしているようですが、pについて11要素確保するっぽい式なのに12要素使っているのも怪しいですね。

こお さんが書きました:今は一文字ずつ読み込んで分岐処理でやろうと思っていましたが、一文字づつカウントアップしてしまいます。

「カウントアップする」とは、ここではどのような意味ですか?

こお さんが書きました:ヒントを頂けると嬉しいです。よろしくお願いします。

まず、文字列を入れたいのにint型を要素とする2次元配列を使っているのはおかしいですよね。
次に、せっかく読み込んだ前の文字を次の文字で上書きしているのも不自然ですよね。

そこで、まず2次元配列の要素の型はchar* (charではない) にしましょう。
そして、読み込んだ文字列をバッファに格納し、区切りが来たら必要十分な長さのメモリを確保して文字列をコピーし、バッファを初期化し、そこへのポインタを2次元配列に格納すればいいでしょう。
擬似コードで書くと以下のようになるでしょう。

コード:

文字列格納バッファを初期化
読み込み終わるまでループ {
    1文字読み込む
    if (読み込んだのが区切り文字) {
        文字列格納バッファの文字列に終端文字を追加する
        文字列を保存する領域を確保する
        その領域にバッファの文字列をコピーする
        その領域へのポインタを2次元配列に格納する
        2次元配列の格納位置を進める
        文字列格納バッファの文字列を空にする
    } else {
        if (文字列格納バッファの容量が足りない) {
            文字列格納バッファの容量を増やす
        }
        文字列格納バッファの文字列に読み込んだ文字を追加する
    }
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

こお

Re: C言語 CSV 格納

#3

投稿記事 by こお » 9年前

とりあえず、21行目で1400要素しかない配列pの範囲外の1400番目(0-origin)の要素に値を書き込んでいるので、未定義動作ですね。
1400のかわりに1600を掛けることでごまかしているようですが、pについて11要素確保するっぽい式なのに12要素使っているのも怪しいですね。

>>まさしくその通りです。理解が浅く、メモリを多く確保すればいいのかな?いった形でやってしまっています汗

「カウントアップする」とは、ここではどのような意味ですか?

>>説明不足でした。一文字ずつ格納されるので、p[0][0]に一文字でけ格納されたらp[0][1]と次の配列に行ってしまうことを言いたかったです。


疑似コードありがとうございます。

閉鎖

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