• ベストアンサー

データの区切り?

こんにちわ。前回質問に御答え頂いて誠に有難う御座います。 さて、今回の質問なんですが、文字列の分割の方法が分からなくて困っています。 以下プログラムです。 //////////////////////////////////////// /*make_date.cpp*/ #include <stdio.h> #include <string.h> #define MAX_LEN 1000 #define MAX_LEN2 1000 #define BUFFER_SIZE 200 int main() { int i, len, cnt = 0; char *cp2; //「カテゴリー」「更新日」「職種」「登録日」 const char *delim2 = ":"; //改行用単語1 const char *delim3 = "@D"; //改行用単語2 const char *delim4 = "@P"; //改行用単語3 const char *delim5 = "@A"; //改行用単語4 const char *delim6 = "@Q"; //改行用単語5 const char *delim7 = "@W"; //改行用単語6 const char *delim8 = "@Z"; //改行用単語7 const char *delim9 = "@C"; //改行用単語8 const char *delim10 = "@T"; //改行用単語9 char buffer[BUFFER_SIZE]; char aiu[100]; char *wordss[MAX_LEN2]; FILE *fp,*pf; //ファイルポインタ //---------------------------------------------------- //各項目を選ぶ処理(カテゴリ) if((fp=fopen("data.dat","r")) == NULL ){ printf( "datファイルが存在しません。\n" ); } wordss[0] = fgets( aiu, 256,fp ); cp2 = wordss[0]; //そして、保存の為、取得したデータを「entry.bk」に入れ込む。 pf=fopen("entry.txt","w"); //区切り処理1 wordss[0] = strtok(cp2, delim9); //文字列に代入されている状態を確認 printf( "\n\n%s", wordss[0] ); //書き込み処理 fputs(wordss[0],pf); cp2 = NULL; //ファイル・クローズ fclose(pf); //ファイル・クローズ fclose(fp); return 0; } //////////////////////////////////////// /*data.dat*/ 20080714@TSE@C20080816@Z公開20090201@WSE@Q20090205@Aテスト20090206@PSE@D20090206:会議 //////////////////////////////////////// 現在このようなプログラムがあります。 「ddata.dat」の中にある文字列の【20080714】だけを取り出し、 「entry.txt」へ書き出します。(「delim10」を使用し「@T」があったら、改行します。) 次に【SE】だけを取り出し、 「se.txt」へ書き出す処理を作成中なんですが、 試しに【SE】を書き出すのかチェックするため「delim9」を使用し、試してみましたが、書き出されるのが【20080714】になってしまいます。 これを【20080714】【SE】【20080816】と書き出すにはどのようにしたら良いでしょうか? 説明が分かり難く申し訳御座いませんが宜しくお願いします。 タイトルも分かり難く申し訳ないです・・

質問者が選んだベストアンサー

  • ベストアンサー
  • arain
  • ベストアンサー率27% (292/1049)
回答No.4

No1.です。 とりあえず他の気になるところも。 >wordss[0] = fgets( aiu, 256,fp ); >cp2 = wordss[0]; 読み込み時の問題はNo.3氏のとおり。 で、 cp2 = fgets( aiu, 256,fp ); とやらない理由は? >pf=fopen("entry.txt","w"); にエラー処理がないのは? >char *wordss[MAX_LEN2]; は「char *wordss[1000];」となるわけだが、ポインタが1000個もいる理由は?

akianaray
質問者

お礼

色々見てみたところ、問題解決まで近づいてきましたので もう少し調べて作成してみます。 何度もご回答有難う御座います。

akianaray
質問者

補足

返信有難う御座います。 そして遅れてすみません。 >cp2 = fgets( aiu, 256,fp ); これはcp2がちゃんとデータを取得してるかをチェックする為にしたためです、確かに「cp2 = fgets( aiu, 256,fp );」にすれば 「printf( "%s", cp2);」と書けば内容は分かりますね・・ >pf=fopen("entry.txt","w"); え~と、すいません・・エラー処理というのは? これも"r"みたいに書き込みされたかどうかをチェックする処理が必要なんでしょうか? >「char *wordss[1000];」となるわけだが、ポインタが1000個もいる理由は? 始めは10にしていたんですが、エラーが表示されてしまう状態になってしまい、数を増やしたら消えたので・・ 少なすぎたのでしょうか・・ 今現在はファイルを別々に作成するプログラムを作成中です。 【20080714】を作成するプログラム、【SE】を作成するプログラム【20080816】を作成するプログラム・・・ ただ、これも今後数が増えた場合・・その度にファイルを作るプログラムを作成しなければなりません・・・

その他の回答 (4)

  • S117
  • ベストアンサー率40% (18/45)
回答No.5

いろいろ突っ込みたいところがたくさんありますが、ほかの回答者が言及してるのでおいておきます。 コードの先頭で、 /*make_date.cpp*/ とありますが、見る限りではCのコードだと思います。微妙な仕様の違いで混乱することがありますのでどっちかはっきりさせた方がいいでしょう。 なお、もしもC++なのであればC++のライブラリの方が使いやすいと思います。以下はCという前提です。 細かいところはともかく最初の部分を取得できていますので、2番目がとれない原因はstrtokの使い方を間違えているのだと思います。一度、使用している処理系のリファレンスでstrtokの使い方を確認した方がいいでしょう。リファレンスを見てもわからないようでしたら、新しく質問するなりしてみてください。また提示されたソースの範囲内でもstrtokに対して使い方を誤解していると思われる部分があります。

akianaray
質問者

お礼

strtok関数の使い方を理解して、作成して見たところ、 問題解決まで近づきました。 もう少しがんばって作成してみます。 ご回答有難う御座いました。

akianaray
質問者

補足

返信有難う御座います。 すいません、遅れてしまいまして・・ >見る限りではCのコードだと思います はい、Cで書いてます。ファイルを保存時に自動的にcppになります。 >2番目がとれない原因はstrtokの使い方を間違えているのだと思います。 どうやらそのようです・・なので、strtok関数について調べてみます。

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.3

>これを【20080714】【SE】【20080816】と書き出すにはどのようにしたら良いでしょうか? 20080816 をどこに書込むかの説明がありません。 >タイトルも分かり難く申し訳ないです・・ そういう自覚があるのでしたら、人にわかりやすく伝えるには どうすればよいかをもっと考えるべきでありましょう。 ところで、本題とは関係ないかもしれませんが、 >char aiu[100]; >wordss[0] = fgets( aiu, 256,fp ); aiuのサイズとfgetsで読込むサイズとが食い違っていてもよいのでしょうか?

akianaray
質問者

お礼

問題解決に近づいて来たので、これでやってみます。 ご回答有難う御座います。

akianaray
質問者

補足

返信遅れて申し訳御座いません・・ >20080816 をどこに書込むかの説明がありません。 「update.txt」というファイルを作成し、そのファイルに書き込みます。 >そういう自覚があるのでしたら、人にわかりやすく伝えるには~ そうですね、質問者が分かり難いなんて書いてはいけませんね・・・ >aiuのサイズとfgetsで読込むサイズとが食い違~ よく見てませんでした・・・変更し忘れていました・・ 正式には256に合わせてます。 現在では各項目を一つ、一つファイルを作成し、 【20080714】は【20080714】だけを作るという風にプログラムを作成する事にしました・・ ただ、ファイルは増える事があるので、新しい項目が出来る度にプログラムを作成するのは・・宜しくないと思ってます、

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

どのようなコードを使って試しているのかが全く分かりません. 「うまくいかない」場合のコード全体を示してください. 実は strtok の仕様でそうなっているかもしれんし.

akianaray
質問者

お礼

strtok関数を調べてたら問題解決まで近づいて来ました。 何とかなりそうです。 ご回答有難う御座いました。

akianaray
質問者

補足

返信有難う御座います。 そして、遅れて申し訳御座いません・・ >どのようなコードを使って試しているのか こちらです↓ /*サンプルプログラム*/ #include <stdio.h> #include <string.h> #define MAX_LEN 100 int main() { int i, len; char str[] = "This is a test", *words[MAX_LEN], *cp; const char *delim = " "; cp = str; for (len = 0; len < MAX_LEN; len++) { if ((words[len] = strtok(cp, delim)) == NULL) break; cp = NULL; } for (i=0; i<len; i++) { puts(words[i]); } return 0; } /*サンプルプログラム*/ >実は strtok の仕様でそうなっているかもしれんし どうやらstrtok関数の使い方をよく理解してないようです・・ それが原因なのかもしれません。調べて見ます。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

環境にによっては、ispunct()で区切り文字に該当するコードはチェックできなかったはず。 @はispunct()に引っ掛かるコード。 他にも[]{}なんかはダメなはず。

関連するQ&A