
このような拡張子は.csvのデータから、各データを構造体に
入れていきたいのですが、うまい読み込み方が思いつかず困っております。読み込み元はこんな感じです。
[ 2007年05月30日 ]
"2007年05月30日(土) 13:07"
"#0001-01"
"人数 1名"
"スパゲティー大盛り \2,000"
"内税 (\1,905) \95"
"合計 \2,000"
"2007年05月30日(土) 13:12"
"#0001-01"
"人数 2名"
"ピザ"
"@1,000x2点 \2,000"
"内税 (\1,905) \95"
"合計 \2,000"
"2007年02月17日(土) 13:23"
"#0001-01"
"人数 3名"
"アイスクリーム \900"
"ピザ"
"@1,000x2点 \2,000"
"内税 (\2,762) \138"
"合計 \2,900"
後に売上の合計、ソートをするため「,」の除去、全角数字の半角化はできるのですが、そこからの各データの分け方、格納方法が思いつきません。
fgetsはきっちり指定したバイト数を読み込み、次の行まで読み込んでくれました。なぜかtxtで開くと横にすべてつながった状態で開いてしまいます。
fscanfは調べてて少し問題ありの関数、というような書き込みを見たような気がするので試しておりません。なるべく避けたいです。
今はfgetcで ”から ”までの範囲を読み込むという方法を試していますが、二次元配列に入るのを嫌がっているので、それを説得中です。
長くなってしまいましたが、よろしくお願いいたします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
(うがった解釈をすると)
>このような拡張子は.csvのデータから、
>各データを構造体に入れていきたい、
けれども、
>後に売上の合計、ソートをするため「,」の除去、
>全角数字の半角化はできるのですが、
>そこからの各データの分け方、格納方法が思いつきません。
と、「,」を除去したから、csvデータが壊れてしまった?
「そこから」→「壊れたものから」?
-------------------------------------------------
(「『,』の除去」はない、として)
>それを説得中です。
>のように表示されたということです。
1.質問者様は現場におられないのですね(事件は・・)。
2.投稿すると、先頭・連続する半角空白は省略される。
こうした中で、なかなか説明するのが、難しそうですが・・。
>何かしらのエディター、エクセル、オープンオフィス等でひらくと
>"2007年05年30日(土)スペース13:07"
>"#0001-01"
>"
>となっていて、fgets でまともに読み込まないので試しに、
>txtで開いてみたら全て改行されず、
☆この文章、理解できません。
1.エディタは、「txt」と違うのですか?
2.エクセルでも・・ですか?
3.エディタとエクセルが同じ結果とは?
4.どうしてここに fgets が出現するのですか?
------------------------------------------
No.3 さんと同様に、
「1行がカンマ区切りのCSVファイルという前提」
で、サンプルソース( strtok() の動作説明)を作ってみました。
《結論》
値段の中の千円を示すコンマが、区切りのコンマとなってしまって・・。
区切りのコンマは、2つの " に挟まれたコンマ限定、とする工夫がいるようです。
案:一旦、エディタで、「 "," 」を「 "/" 」と一括変換したファイルを作成する。
次に、下の cCut 「 ,\"\n 」を「 /\"\n 」としたプログラムで「格納」する。
------------------------------------------
#include<stdio.h>
#include<string.h>
void main()
{
char *p, *pTokn;
char cWord[256] = "\"abc\",\"1,230\",\"4,560\",\"7890\"\n";
char cCut[8] = ",\"\n";
printf( "%s", cWord );
p = cWord;
while( NULL != ( pTokn = strtok( p, cCut ) ) ){
printf( "%s\n", pTokn ); // strcpy( cStore[ iLine ][ iCell++ ], pTokn );
p = NULL;
}
}
注:インデントに全角空白を用いています。タブに一括変換して下さい。
私の説明が下手でご迷惑おかけします。
txtで開くというのは、メモ帳で開くという意味です。メモ帳もエディターでした。スイマセン。
エクセル、オープンオフィスなどでひらくと、一行ごとに改行されて
表示されるのですが、メモ帳で開くと、改行されずに横につながって表示されてしまいます。
私がカンマを取り除いて、csvファイルを破損させたといわけではなく、最初からこのファイルはカンマでデータを分けていません。
カンマは¥1,000などの表示に使われてます。
csvという形式で保存されてはいますが、csv形式といえる書き方はされていません。
よろしければ、一行ごとにstrtok関数で分けた後、分けたデータの保存先を判断するコードのサンプルなど頂ければありがたいです。
日時は日時用の変数へ、
商品名は商品名用の変数へ、
単価は単価用の変数へ、
合計は合計用の変数へ、
今、ちょうどこの部分で悩んでいるのでよろしくお願いします。
No.4
- 回答日時:
if(c == 13)
これがあると言うことは改行コードが"CR"と言うことですね。
vistaでvs2008ExplessEditionsということですがfopenでテキストファイルを読み込んだ場合"CR+LF"は"LF"に自動変換されます。"LF"だけや"CR"だけの場合はそのままです。
"CR"が残っているということはつまり元のファイルの改行形式が"CR"のみと考えられます。
fgetsでは"CR"は判定されないと思うので元のファイルの改行形式を変えるのが手っ取り早いと思います。
>CR+LFがLFに自動変換され、CRだけだった場合はそのまま残る。
知りませんでした、ありがとうございます。このままではfgets関数は使えないというわけですね。
元ファイルの改行形式をかえるには、一文字ずつ読み込んでいくと同時に別ファイルに書き出していき、
if(c==13)で一致した場合はcの値を\nに変えて別ファイルに書き出していくという方法でよろしいでしょうか?

No.3
- 回答日時:
念のため確認ですが、
>txtで開いてみたら全て改行されず、
>2007年05月30日(土) 13:07","#0001-01","人数 1名","スパゲティー大盛り \2,000","内税 (\1,905) \95","合計 \2,000"
>のように表示されたということです。
ここで、txtとは何でしょうか。メモ帳のことですか?
データが、どうなっているのか、正確な判断が出来ませんが、
総合的に判断して、1行がカンマ区切りのCSVファイルという前提で、回答します。
1.まず、読込は、fgetsを使用して下さい。そのとき、1行のバッファを非常に大きくとって下さい。
2.つぎに、カンマごとに、データを区切って取り出して下さい。
strtok関数をつかうと、できます。
3.つぎに、取り出したデータの両端にダブルクオートがあれば、それを削除します。
4.これが、1つの項目になりますので、これを構造体に格納します。
色々と私の説明が間違っていたり、説明不足だったりでご迷惑おかけします。
txtで開くというのは、メモ帳で開くという意味です。メモ帳もエディターでした。スイマセン。
一つ一つのデータなのですが、カンマでは区切っておらず、
エクセルなどでいうと、Aの列のセルにすべてはいってます。
一行目のAのセルに ”2007年02月17日(土) スペース13:23”が入って
二行目のAのセルに "#0001-01" が入っているというならびになってます。
strtok関数使ってみました。
strtok関数でスペースをキーにして分けた場合、
分けたデータがどこに入るかを判断しなければならないのですが、
考え方としては読み込んだデータを「人数」という文字列で検索をかけて、見つかった場合はそれ以降のデータを、
今度は「合計」という文字列で検索をしていき、一致するまで全て
商品名とする。という考え方で合っていますでしょうか?
strtok関数でデータ分けする場合、この方法しか思いつかなかったもので。合っているのでしたら、サンプルコードなど載せていただければありがたいです。
よろしくお願いします!

No.2
- 回答日時:
確認ですが、データは、以下のようになっているのですか?
"2007年05月30日(土) 13:07"・・・・1行目
"#0001-01"・・・・2行目
"人数 1名"・・・・3行目
"スパゲティー大盛り \2,000"・・・・4行目
"内税 (\1,905) \95"・・・・5行目
"合計 \2,000"・・・・6行目
それとも、1行目に以下のようにデータがあるのですか?
"2007年05月30日(土) 13:07","#0001-01","人数 1名","スパゲティー大盛り \2,000","内税 (\1,905) \95","合計 \2,000"
ここに載せるときに半角のスペースが省略されてしまったようです。
実際には、1行目は(土)スペース*20個ほどで13:07"となっています。行末の " が大体49バイト目に来ているのですが、
この場合5行目だけ、移行内税の行だけ少し早く、30バイト目くらいに " があります。
説明不足で申し訳ありません。何かしらのエディター、エクセル、オープンオフィス等でひらくと
"2007年05年30日(土)スペース13:07"
"#0001-01"
"
"
"
となっていて、fgetsでまともに読み込まないので試しに、
txtで開いてみたら全て改行されず、
2007年05月30日(土) 13:07","#0001-01","人数 1名","スパゲティー大盛り \2,000","内税 (\1,905) \95","合計 \2,000"
のように表示されたということです。
while((c = fgetc(fp)) != EOF);
でEOFまで変数cに全て読み込むと、
if(c == 13)
{
printf("\n");
}
で、一応は改行できているので、今はfgetcを使って読み込んでます。
5行目の場合、
"内税"スペース"(\1.905)"スペース\95"
という形です。
文字列を分ける、文字列を比較、文字列を抽出するため、
strstr関数、strchr関数を使ってみましたが、
いずれも私の力量が及ばないのか、満足できる結果は得られませんでした。
つたない文章で申し訳ないです。気になる点等ありましたら、
お手数ですがまた、ご指摘下さい。
よろしくお願いいたします。
No.1
- 回答日時:
差し支えなければ、どういうコードを書かれたかを示していただけますか?
ところで、
> 二次元配列に入るのを嫌がっているので、それを説得中です。
お客さんか誰かがいやがっているので説得しているところなのですか?
主語がないため、文意がつかめませんでした。
試した書き方は、
fgetsが私の持っている参考書で指定バイト数か、改行文字まで読み込むとあったので、
fgets(str,50,fp) //str[51]という変数の宣言をしていたとします。
全て一行の横の長さは50バイトで収まってました。
読み込んでみたのですが、30バイト目で次の行に行っていると、次の行で残り20バイトしっかり読み込みます。
今試しているコードは、
while((c = fgetc(fp)) != EOF)
{
if(c == '"')
{
while((c = fgetc(fp)) != '"')
{
次の”まで一バイトずつ配列に入れていく。
}
入れ終わったらy軸をインクリメントして次の行へ移行。
}
}
なのですが、これだと全部の行を配列に入れてしまいます。
そのため、if文で格納すべき行としない行を判別しているのですが、
全ての行の頭に”がついているため、てこずってます。
”の次のバイトにある全角の最初の1バイトめはchar型で判断してみたのですが、それ以降の文字列の中に同じ数値が含まれていたりして文字化けしました。¥マークでの判別も、商品によって(メとかラの頭1バイト)でかぶっているためやめました。
wchrt_t型で”の次の文字を判別しようとすると表示、書き込みの際に文字化けしてしまいます。
問題が変わってしまうのですが、これはやはり文字コードの問題なのでしょうか? 開発環境はvistaでvs2008ExplessEditionsです。
だとしたら、自分の開発環境の文字コードは何なのでしょう?
jisかsjisだと思ってましたが、教えて頂けますでしょうか。
構造体への格納方法共々、自分の使用している文字コード?
の規格の調べ方も大変申し訳ないのですが、よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- Excel(エクセル) エクセルでSUMIFS関数で条件範囲の部分が#valueになる。 4 2023/04/28 12:42
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- 中途・キャリア 契約社員で在職中ですが、正社員目指して転職活動中です。 20代半ばの男です。 2社から内定を頂きまし 5 2022/04/29 13:39
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
- その他(住宅・住まい) 築15年マンションで発生した玄関扉の不具合を販売主へ契約不適合責任を請求できますか? 3 2023/02/28 10:47
- Excel(エクセル) エクセル365の関数。誕生日表記がおかしい 2 2022/10/17 18:52
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
空白文字 \\f と\\v の違いに...
-
【Access2003】VBAでタブ区切り...
-
Edge スクレイピング
-
重複するデータを抽出できる秀...
-
エクセルVBA コードが同じでも...
-
Windowsで複数のファイルを同じ...
-
fgets で値が取得できない
-
ReadLineでの読み出し行を指定する
-
MATLAB グローバル変数の宣言
-
配列の中に重複文字列があるか...
-
VBAでCSVファイルを途中行まで...
-
MATLABでのwhile文の条件について
-
vba dir の相対パス
-
無料配布の郵便番号自動入力cgi...
-
行を指定して削除する方法PERL
-
openした後、closeしないでプロ...
-
エラー 'dir.h' : No such fi...
-
perlのflock関数でロックをかけ...
-
サーバーにある特定の拡張子フ...
-
[Perl]ファイル出力のエンコー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチファイルの作り方(CSV→...
-
C言語で特定の行を抽出する方法...
-
空白文字 \\f と\\v の違いに...
-
全角と半角文字が混在している...
-
Edge スクレイピング
-
【Access2003】VBAでタブ区切り...
-
【エクセル】改行無しテキスト...
-
VBAでタブ区切りテキストの保存...
-
\\tはどんなときに使うのでしょ...
-
タブコントロールに付いて
-
Javaのコーディングスタイル
-
エクセルのデータをテキストデ...
-
タブの色を変更する方法
-
デルファイ TabControl タブの...
-
エクセル→XML 要素のコピー
-
掲示板の過去ログDLについて
-
Access2007のADOの使い方が分か...
-
AccessからExcelをタブ指定で開...
-
Excelのマクロで改行を含んだテ...
-
テキストファイル(tsv)を改行...
おすすめ情報