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

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

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

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

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Q&A

解決済

5回答

1097閲覧

【c】検索した文字列と同一の記事を取得したいです.

studyprg

総合スコア57

C

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

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

0グッド

0クリップ

投稿2022/07/03 13:08

編集2022/07/06 12:49

やりたいこと

自然言語処理について勉強しています。
Wikipediaのdumpデータから本文を抜き出して処理をしようと思ってます。
xmlの処理について試しているのですが、出力結果が想定とは違って困っています。

やりたいこととしては以下です.
・list_history0.txt の各行が欲しい記事の "タイトル" を示している。
・get_X1.txt の各行が (xml ファイル内の記事の ) "タイトル", "id", "開始バイトオフセット", "バイトサイズ" を示している。
・list_history0.txt から一行ずつ読み込み、 get_X1.txt からタイトルが一致する行を探して"開始バイトオフセット", "バイトサイズ"を利用して xml ファイルからその記事を取り出し、「タイトル(タブ)id(改行)記事」を history_0text.txt に書き出す

プログラミングはあまり得意ではないです。

ソースコードとファイル構成

list_history0.txt(get_X1.txtの一部)

日本ゴルフツアー機構 ファイル:十弗駅看板.jpg 桂米朝 国道101号 笑福亭松鶴 リサジュー図形 ムラカ 日淳 井原裕士

次にget_X1.txt

遠山景晋 493646 2948 0 双子 (映画) 1011517 13316 12558 ユダヤ史関連人物の一覧 1855796 18478 68347 Trip trip 56477 87361 0 新銀行東京 615917 91374 90824 東京都道444号下石神井大泉線 61977 144134 143579 野川さくら 1485326 147328 146788 リメンバー・ミー 1740912 231113 230616 ダヒル・リヤレ・カヒン 787401 233208 232520 ソマリランドの大統領一覧 1094317 237068 236399 バルティ 1094317 242216 3511 歌がチカラ 56477 246360 0 トーンチャン 994927 250016 1231 北海道道145号伊達インター線 1428473 251833 0 アクセス禁止 97976 255003 254438 蒲池城 928380 274271 1331 新潟地震 1583832 276296 0 長崎貿易 872478 310391 309847 春牟古丹島 730521 319037 318416 スター誕生! 1873614 325384 324878 サーキット 1037035 456227 455590 Wikipedia:今日は何の日 9月 597321 510011 44598 WP 1617964 555804 2507 栄町駅 (札幌市) 366911 558992 0 北海道中央バス 1599928 574344 573819 広島電鉄1300形電車 6896 668607 668053 柳川鍋 924713 669194 668686 京都市内の通り 191555 676990 37953 由布岳 918416 715450 0 HN 1486874 724007 723488 コンセルヴァトワール 910758 724984 724479 玉川砂記子 1094317 729024 728336 シラガゴケ類 397108 782982 782331 NC 059668 785975 5126 スギゴケ 1781685 791744 0 摂津源氏 990884 794923 794341 NE 262022 805690 805156 NG 1718990 808263 807633 源氏嫡流 279186 810908 810440 魔性の子 1680100 819840 819300 NI 474 844662 844142 NL 104512 846162 845675 翼細胞 208476 847883 847316 NO 230804 848873 848430 多田源氏 990884 850953 850420 NR 786173 863825 863328 フワランポーン駅 1356379 866728 866158 キングカメハメハ 1693773 886601 886041 OM 387704 978075 977510 苔 826261 980849 980395 徐世昌 16765 988907 988200 NY市警緊急出動部隊 トゥルー・ブルー 791294 997442 996895 PE 1627601 1006180 3452 セラミック噴射装置 3751 1010197 0 堀内賢雄 12357 1010829 1010266 筑後宇都宮氏 575671 1197925 1197423 リンカーン (競走馬) 194189 1202581 1201984 PK 703098 1223633 3515 真田町 1231761 1229043 6504 トンファー 503710 1236096 0 情報処理技術者試験 444436 1244748 1244203 キングマンボ 1728221 1308947 1308351 イースター (曖昧さ回避) 120987 1322716 1322186 田中新兵衛 760804 1324023 1323537 PR 703098 1331531 1331062 PT 665832 1336401 1335869 高橋俊昌 291984 1341864 1341250 PW 136753 1350315 1349839 坂城町 685790 1352052 1351543 セレン整流器 1094317 1362107 1361338 ポリアクリルアミドゲル電気泳動 520484 1365670 1365099 シェルピンスキー数 990884 1371139 1370494 はだしのゲン 1126159 1379494 1378926 伊王島町 1338147 1525866 1525301 ノイローゼ 371027 1539066 1538569 原子力発電所 1084393 1540501 1539942 宮崎県総合運動公園第二硬式野球場 320096 1569579 7259 藤田瞳子 1094317 1578500 6210 赤外分光法 1768613 1585235 0 宇都宮清原工業団地 850234 1599642 1599097 樊噲 262022 1603667 1603179 国道385号線 7146 1611313 1610756 深川 1094317 1612117 1611379 碓氷第三橋梁 308365 1616321 5517         //読み込みたいところ 日本ゴルフツアー機構 870371 1623035 25562 ファイル:十弗駅看板.jpg 1780509 1649736 682 桂米朝 1589144 1652031 1217 国道101号 643806 1654059 0 笑福亭松鶴 1143138 1672954 1672423 リサジュー図形 1037035 1682479 1681821 ムラカ 885381 1691394 14441 日淳 1037035 1706472 0 井原裕士 308365 1710132 1709601         //読み込みたいところここまで ソマリア内戦 1037035 1714267 36576 深川 (江東区) 020100 1751367 0 日昇 833366 1764959 1764447 以下略

次にソースコードです.//追記に現在のソースを追加してます.

#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p = 0; int pb[3] = {}; char *line = malloc(SIZE); char *title = malloc(SIZE); char *id = malloc(SIZE); char *text = malloc(SIZE); char *stitle=malloc(SIZE); FILE *fp = NULL; FILE *fr = NULL; FILE *fr2 = NULL; FILE *gt = NULL; fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r");//大元.wiki記事 fr = fopen("list_history0.txt", "r"); //読み込むファイル検索文字列 fr2 = fopen("get_X1.txt", "r");//読み込むファイル2タイトルとidが記入 gt = fopen("history_0text.txt", "w"); //書き込むファイル while (fscanf(fr, "%s\n", stitle) != EOF) { printf("Stitle(検索対象)is %s.\n", stitle); while (fscanf(fr2, "%s\t%s\t%d\t%d\n", title, id, &pb[0], &pb[1]) != EOF) { printf("確認用title:%s\tID:%s\n",title,id); if ((strcmp(stitle, title) == 0)) //タイトルが見つかった時. { printf("%s is found! title:%s\n", stitle, title); fseek(fp, pb[0], SEEK_SET); fgets(text, pb[1], fp); printf("%s\t%s\n%s", title, id, text); } else { continue; } } } printf("\n\n\nprocess ok!\n\n\n"); fclose(fp); fclose(fr); fclose(fr2); fclose(gt); }

一応現在の実行結果です.

追記:

今のソースコードです.
タイトルとid処理を一通りやって終わってるようです.
以下ソースコードと実行結果です.idとタイトルは表示できてるようです.

#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p = 0; int pb[3] = {}; char *line = malloc(SIZE); char *title = malloc(SIZE); int *id = malloc(SIZE); char *text = malloc(SIZE); char *stitle=malloc(SIZE); FILE *fp = NULL; FILE *fr = NULL; FILE *fr2 = NULL; FILE *gt = NULL; fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r");//大元.wiki記事 fr = fopen("list_history0.txt", "r"); //読み込むファイル検索文字列 fr2 = fopen("get_X1.txt", "r");//読み込むファイル2タイトルとidが記入 gt = fopen("history_0text.txt", "w"); //書き込むファイル while (fscanf(fr, "%s\n", stitle) != EOF) { printf("Stitle(検索対象)is %s.\n", stitle); fr2 = fopen("get_X1.txt", "r"); while (fscanf(fr2, "%s\t%d\t%d\t%d\n", title, id, &pb[0], &pb[1]) != EOF) { printf("確認用title:%s\tID:%d\n",title,id); if ((strcmp(stitle, title) == 0)) //タイトルが見つかった時. { printf("%s is found! title:%s\n", stitle, title); fseek(fp, pb[0], SEEK_SET); fgets(text, pb[1], fp); printf("%s\t%d\n%s", title, id, text); } else { continue; } } fclose(fr2); } printf("\n\n\nprocess ok!\n\n\n"); fclose(fp); fclose(fr); fclose(gt); }

cmd

1 2確認用title:警察学校 ID:1463812096 3確認用title:ファイル:Kasai-ichijyoji-kaizan1.JPG ID:1463812096 4確認用title:Template:石勝線 ID:1463812096 5確認用title:ロドピ山脈 ID:1463812096 6確認用title:ボブ・ゲルドフ ID:1463812096 7確認用title:Template:根室本線2 ID:1463812096 8確認用title:商船三井ビルディング ID:1463812096 9確認用title:Template:根室本線1 ID:1463812096 10確認用title:ファイル:Kasai-ichijyoji-Jougyoudou.JPG ID:1463812096 11確認用title:Category:干潟 ID:1463812096 12確認用title:Template:根室本線3 ID:1463812096 13確認用title:ジュゼッペ・マッツィーニ ID:1463812096 14確認用title:総括制御 ID:1463812096 15確認用title:羽車 ID:1463812096 16確認用title:Template:釧網本線 ID:1463812096 17確認用title:劇団たいしゅう小説家 ID:1463812096 18確認用title:応急手当普及員 ID:1463812096 19確認用title:河内十人斬り ID:1463812096 20確認用title:Template:石北本線 ID:1463812096 21確認用title:宇佐美-網代バイパス ID:1463812096 22確認用title:ファイル:Kasai-ichijyoji-33jizo.JPG ID:1463812096 23確認用title:鈴木邦彦 ID:1463812096 24確認用title:(作曲家) ID:1463812096 25確認用title:島根県道201号湯里停車場祖式線 ID:1463812096 26確認用title:Template:宗谷本線 ID:1463812096 27確認用title:ゴーロン星人 ID:1463812096 28確認用title:ロベルト・デュラン ID:1463812096 29確認用title:アフォンソ1世 ID:1463812096 30確認用title:(ポルトガル王) ID:1463812096 31確認用title:グルンヴァルト ID:1463812096 32確認用title:島根県道186号美郷大森線 ID:1463812096 33確認用title:堀内昭義 ID:1463812096 34確認用title:ファイル:Akame48Taki-iriguchi.JPG ID:1463812096 35確認用title:出雲バイパス ID:1463812096 36確認用title:アズバーズ ID:1463812096 37確認用title:大沢悠里のにっぽん元気カンパニー ID:1463812096 38確認用title:堀口健治 ID:1463812096 39確認用title:島根県道288号瓜坂川合線 ID:1463812096 40確認用title:トヨタ・M型エンジン ID:1463812096 41確認用title:パルマラット ID:1463812096 42確認用title:地名に由来する小惑星の一覧 ID:1463812096 43確認用title:Wikipedia:削除依頼/アルバムの一覧 ID:1463812096 44確認用title:人名に因む名を持つ小惑星の一覧 ID:1463812096 45確認用title:日本神話に関する名を持つ小惑星の一覧 ID:1463812096 46確認用title:吾妻橋 ID:1463812096

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

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

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

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

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

y_waiwai

2022/07/03 13:42

で、問題はなんでしょうか
studyprg

2022/07/03 13:44

実行結果が見つかってない時の処理になっていてこれを見たかった時に行う処理を行えるようになりたいです。 結論から言うとhistory0textを中身がある状態で取得したいです
y_waiwai

2022/07/03 13:47

質問文は編集できるので、そっちに追記しよう。 何を聞きたいのか説明しよう #いまだ質問がなにか不明
jimbe

2022/07/03 15:22 編集

>検索したい記事の文字列(list_history0.txt)が記事のタイトル,id,記事の開始バイトと記事のサイズのバイトが記入されているファイル(get_X1.txt)のタイトルが同一の時に記事の開始バイトと記事サイズのバイトを読み込んでテキストファイル(history_0text.txt)に書き込んでいきたいです. 文章を詰め込み過ぎです。 ・list_history0.txt の各行が欲しい記事の "タイトル" を示している。 ・get_X1.txt の各行が (xml ファイル内の記事の ) "タイトル", "id", "開始バイトオフセット", "バイトサイズ" を示している。 list_history0.txt から一行ずつ読み込み、 get_X1.txt からタイトルが一致する行を探して xml ファイルからその記事を取り出し、「タイトル(タブ)id(改行)記事」を history_0text.txt に書き出す…ということでしょうか。 > printf("%sは見つかりませんでした.\n", stitle); のことを「見つかっていない時の処理」と表現されているようですが、この表示は見つかっても見つからなくても実行される状態です。 >見たかった時に行う処理 「見つかった時に行う処理」の誤字でしょうか。 >history0textを中身がある状態で取得したい つまり現状は「出力されるはずのファイルに中身が無い」ということでしょうか。 表現が独特です。
jimbe

2022/07/03 15:27 編集

少なくともファイルが読み込めているか等の確認をしていないのでしょう。 fr2 が全く使われておりません。
studyprg

2022/07/03 15:29

一応frとgoの読み込みは確認しているはずです。 fr2を組み込んだのが今の状態です。
thkana

2022/07/03 15:29

すでに指摘はありますが、 > 検索したい記事の文字列(list_history0.txt)が記事のタイトル,id,記事の開始バイトと記事のサイズのバイトが記入されているファイル(get_X1.txt)のタイトルが同一の時 日本語として読めません。 「なに」と「なに」とが同一だというのでしょう? (こういうのがちゃんと整理して書けないようだと、それはプログラムに影響しますから...)
studyprg

2022/07/03 15:30

jimbeさんの0:22のやつですが 全くもってその通りだと思います。
studyprg

2022/07/03 15:32

thanksさん "history0.txtに格納されている文字列(記事のタイトル名)"が、"get_x1.txtの記事のタイトル名"と同一の時に取得したいです。 言い方あってますかね?
jimbe

2022/07/03 16:01

>一応frとgoの読み込みは確認しているはずです。 go とは何でしょう。 もし gt のことでしたら、 コード内でコメントされている通り「書き込むファイル」ですので読む必要は無いものと思いますが…。 >fr2を組み込んだのが今の状態です。 組み込んだのでしたら、これも読めているか確認するべきではないでしょうか。
studyprg

2022/07/03 16:12

確認しますね
studyprg

2022/07/03 16:13

わかりました fr2をよみこまなあかんとこにgym指定してますね。
studyprg

2022/07/03 16:41

文言の修正と現在のソースコードを書き込みました.
dodox86

2022/07/04 00:26

書き込みたいと言うファイルはfopenで開いているだけで書いていないし、"get_X1.txt"を開いてfscanfで読み続けていますが、いったんファイルの最後まで読んだら終わりになってるように見えます。このご質問に限らず「プログラミングはあまり得意ではないです」と注意書きがありましたが、現状のコードでは明らかに処理が足りないです。 「要望どおりに動かすにはどうコードを追加して直したら良いでしょうか」とのような質問なのでしょうか。
Zuishin

2022/07/04 00:56 編集

ちなみに、C 言語である必要があるんでしょうか? 他の言語であれば数行でできるような処理ではないかと思います。 あと XML は関係ありませんね。TSV だと思いますが、TSV ということすらも質問にはほとんど関係ありません。
studyprg

2022/07/04 02:50

dodox86さん そうですね。 どのようにしたらいいですかね? ご教授願いませんか?
studyprg

2022/07/04 02:51

zuishinさん  削除しておきます。
Zuishin

2022/07/04 02:55

無視は「わかりきったことを聞くな」という意味ですか?
studyprg

2022/07/04 02:56

そんなに怒らないでほしいです。 tagについて知らなかったぼくの落ち度です。
Zuishin

2022/07/04 03:05

タグだけではなく質問中に多く xml と書いてありますが、私の言っているのはそれではありません。 C 言語でなければ簡単に済むのに、なぜわざわざ C 言語なのかと聞いています。
Zuishin

2022/07/04 03:06

行数が増えると読めないというだけなら、分割して書きます。
jimbe

2022/07/04 03:08

>文言の修正と現在のソースコードを書き込みました. コードが変わりますと実行結果も変わると思うのですが、結果のほうが書き換えられていないように見えます。 どうなりましたでしょうか。
studyprg

2022/07/04 03:08

c言語なのは縛りみたいなものですね。 今までcでやってきたので ソースごとにコロコロ言語変えるのは一貫性ないなあと思ってます。 一応これでxml関係は終わりのはずなので。
Zuishin

2022/07/04 03:15

繰り返しますが、xml は無関係です。 一貫性どころか、何も学習できていません。
studyprg

2022/07/04 03:16

jimbeさん なんもかわってないっすね。
jimbe

2022/07/04 04:26 編集

出力ファイルへの書き込みに関しましては(そもそも書き込み処理がありませんので)変わっていないと思いますが、少なくとも > printf("%sは見つかりませんでした.\n", stitle); が無くなっていますので表示は変わったはずですね。 プログラミングに対してあまり積極的になれないようですが、本件は回答側が取り出し元の xml データにアクセス出来ませんので、プログラムの実行結果は studyprg さんにご提示頂くしかありません。 データ・コード・結果が一貫していないと、どれが正しいのか分からなくなります。 プログラムとしては「//タイトルが見つかった時.」の if 文が成立しなければなりませんので、なぜ成立していないのかを調べる必要があります。 if 文の strcmp のパラメータ stitle と title のうち、 title は "char *title = malloc(SIZE);" として領域確保・アドレス設定をしていますが、 stitle は如何でしょう。"char *stitle;" としか書かれておらず、その領域・アドレスは全く不明です。これは、どこかのメモリ内容を破壊しながら動作していることを意味します。 まずは stitle に領域を設定しては如何でしょうか。 また、stitle と同じように、 fr2 の scan 後に title や id を表示して読めているかを見るというのもテだと思います。 それらによってどのような結果になるのか、その結果から何が想像され、さらにそれを確認するにはどうすれば良いのかを考えてみてください。
studyprg

2022/07/04 04:47

わかりました 調べて提示しますね
studyprg

2022/07/04 05:46

jimbeさん 一応実行結果です. Stitle(検索対象)is 日本ゴルフツアー機構. Stitle(検索対象)is ファイル:十弗駅看板.jpg. Stitle(検索対象)is 桂米朝. Stitle(検索対象)is 国道101号. Stitle(検索対象)is 笑福亭松鶴. Stitle(検索対象)is リサジュー図形. Stitle(検索対象)is ムラカ. Stitle(検索対象)is 日淳. Stitle(検索対象)is 井原裕士. process ok!
studyprg

2022/07/04 06:52

idとタイトルも一部入れ替わってるみたいですね.
jimbe

2022/07/04 11:20

tatsu99 さんの回答のほうで解析(?)が進んでおられるようですので、枝を分けない為にこちらでは一旦止めたほうが良さそうです。
guest

回答5

0

ベストアンサー

修正ソースです。
wiki_parserX.c

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define SIZE (256 * 1024 * 1024) 5 6int main() 7{ 8 9 int p,pb[6] = {0,0,0,0,0,0}; 10 char *line = malloc(SIZE); 11 char *title; 12 char *id; 13 char *titletext; 14 char *idtext; 15 char *t0; 16 char *t1; 17 int tlen; 18 FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); 19 FILE *fw = fopen("get_all_byte.txt", "w"); //記入先 20 if ((NULL == fp) || (NULL == fw)) 21 { 22 printf("ファイル読み込み失敗!!!!!!!!!!!!\n"); 23 abort(); 24 } 25 while (p = ftell(fp), fgets(line, SIZE, fp)) 26 { 27 28 // title 29 if (t0 = strstr(line, "<title>")) 30 { 31 // printf("title(patarn1) found.\n"); 32 pb[0] = p; 33 if ((t1 = strstr(line, "</title>"))) 34 { 35 // printf("/title(patarn1) found.\n"); 36 tlen = t1 - t0 - strlen("<title>"); 37 pb[0] = p + t0 -line + strlen("<title>"); 38 pb[1] = tlen; 39 pb[2] = 0; 40 pb[3] = 0; 41 continue; 42 } 43 } 44 // id用 45 if (t0 = strstr(line, "<id>")) 46 { 47 if (pb[2]!= 0) continue; 48 if ((t1 = strstr(line, "</id>"))) 49 { 50 tlen = t1 - t0 - strlen("<id>"); 51 pb[2] = p + t0 -line + strlen("<id>"); 52 pb[3] = tlen; 53 continue; 54 } 55 } 56 57 // text 58 if (t0 = strstr(line, "<text")) 59 { 60 t0 = strchr(t0,'>'); 61 pb[4] = p + t0 -line + 1; 62 } 63 64 if (t1 = strstr(line, "</text>")) 65 { 66 pb[5] = p - pb[4] + t1 -line; 67 } 68 if (pb[0] > 0 && pb[1] > 0 && pb[2] > 0 && pb[3] > 0 && pb[4] > 0 && pb[5] > 0) 69 { 70 //printf("pb[0](title seek point):%d\npb[1](title size):%d\npb[2](id start point):%d\npb[3](id size):%d\npb[4](text start point):%d\npb[5](text size):%d\n\n\n\n", pb[0], pb[1], pb[2], pb[3], pb[4], pb[5]); //目的達成のため,値を初期化 71 fprintf(fw,"%d\t%d\t%d\t%d\t%d\t%d\n",pb[0],pb[1],pb[2],pb[3],pb[4],pb[5]); 72 pb[0] = 0; 73 pb[1] = 0; 74 pb[2] = 0; 75 pb[3] = 0; 76 pb[4] = 0; 77 pb[5] = 0; 78 } 79 } 80 printf("process ok"); 81 free(line); 82 fclose(fw); 83 fclose(fp); 84} 85

wiki_getterX.c

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define SIZE (256 * 1024 * 1024) 5int main() 6{ 7 8 int p, p1 = 0; 9 int pb[6] = {}; 10 char *line = malloc(SIZE); 11 char *title = malloc(SIZE); 12 char *id = malloc(SIZE); 13 FILE *fp = NULL; 14 FILE *fr = NULL; 15 FILE *gt = NULL; 16 fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); 17 fr = fopen("get_all_byte.txt", "r"); //読み込むファイル 18 gt = fopen("get_X1.txt", "w"); //書き込むファイル 19 while (fscanf(fr, "%d\t%d\t%d\t%d\t%d\t%d\n", &pb[0], &pb[1], &pb[2], &pb[3], &pb[4], &pb[5]) != EOF) 20 { 21 fseek(fp, pb[0], SEEK_SET); 22 fread(title, 1, pb[1], fp); //タイトル取得 23 title[pb[1]] = '\0'; 24 fseek(fp, pb[2], SEEK_SET); 25 fread(id, 1, pb[3], fp); // id取得 26 id[pb[3]] = '\0'; 27 fprintf(gt, "%s\t%s\t%d\t%d\n", title, id, pb[4], pb[5]); 28 } 29 printf("process ok"); 30 free(line); 31 free(title); 32 free(id); 33 fclose(fp); 34 fclose(fr); 35 fclose(gt); 36} 37

3番目のファイル

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define SIZE (256 * 1024 * 1024) 5#define MAX_REC (300000) 6typedef struct { 7 char title[256]; 8 char id[128]; 9 int pb1; 10 int pb2; 11} X1_INFO; 12int main() 13{ 14 15 int ll; 16 int i; 17 int x1_ctr = 0; 18 char *p; 19 X1_INFO *wx1; 20 char pb1[16]; 21 char pb2[16]; 22 char *line = malloc(SIZE); 23 char *title = malloc(SIZE); 24 char *id = malloc(SIZE); 25 char *text = malloc(SIZE); 26 char *stitle=malloc(SIZE); 27 X1_INFO *x1ptr = malloc(sizeof(X1_INFO)*MAX_REC); 28 if (x1ptr == NULL){ 29 printf("X1_INFO allocate error\n"); 30 return 10; 31 } 32 FILE *fp = NULL; 33 FILE *fr = NULL; 34 FILE *fr2 = NULL; 35 FILE *gt = NULL; 36 fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r");//大元.wiki記事 37 fr = fopen("list_history0.txt", "r"); //読み込むファイル検索文字列 38 fr2 = fopen("get_X1.txt", "r");//読み込むファイル2タイトルとidが記入 39 gt = fopen("history_0text.txt", "w"); //書き込むファイル 40 //get_X1を全て読み込む 41 while(fgets(line,SIZE,fr2) != NULL){ 42 if (x1_ctr >= MAX_REC){ 43 printf("Max Record Count Over:%d\n",MAX_REC); 44 return 10; 45 } 46 ll = strlen(line); 47 p = strtok(line,"\t\n"); 48 strcpy(title,p); 49 p = strtok(NULL,"\t\n"); 50 strcpy(id,p); 51 p = strtok(NULL,"\t\n"); 52 strcpy(pb1,p); 53 p = strtok(NULL,"\t\n"); 54 strcpy(pb2,p); 55 wx1 = x1ptr + x1_ctr; 56 strcpy(wx1->title,title); 57 strcpy(wx1->id,id); 58 wx1->pb1 = atoi(pb1); 59 wx1->pb2 = atoi(pb2); 60 x1_ctr++; 61 } 62 while(fgets(line,SIZE,fr) != NULL){ 63 ll = strlen(line); 64 if (line[ll-1] = '\n' && ll > 0) line[ll-1] = '\0'; //改行削除 65 strcpy(stitle,line); 66 printf("Stitle(検索対象)is %s.\n", stitle); 67 for (i = 0; i < x1_ctr; i++){ 68 wx1 = x1ptr + i; 69 if (strcmp(wx1->title,stitle) == 0){ 70 printf("%s is found! title:%s\n", stitle, wx1->title); 71 fseek(fp, wx1->pb1, SEEK_SET); 72 memset(text,0x00,SIZE); 73 if (wx1->pb2 > 0){ 74 fread(text,1,wx1->pb2, fp); 75 } 76 printf("%s\t%s\n%s\n", wx1->title, wx1->id, text); 77 fprintf(gt,"%s\t%s\n%s\n", wx1->title, wx1->id, text); 78 break; 79 } 80 } 81 if (i == x1_ctr){ 82 printf("%s is not found!\n", stitle); 83 } 84 } 85 printf("\n\n\nprocess ok!\n\n\n"); 86 fclose(fp); 87 fclose(fr); 88 fclose(fr2); 89 fclose(gt); 90} 91

投稿2022/07/06 03:21

tatsu99

総合スコア5424

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

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

studyprg

2022/07/06 03:49

本当にありがとうございます!
guest

0

wiki_parserX.cを拝見しました。
いくつか考えられる問題点です。
1.タイトルの情報について
①pb[0]が、タイトルの開始位置になっていない。
タイトルの開始位置-1なので、wiki_getterX.cで+1している。
②pb[1]へタイトルの長さではなく、</title)の開始位置をセットしている。
タイトルの長さを設定したほうが、良いと考える。

2.IDの情報について
1つのタイトル内にIDが複数存在するケースを考慮していないように思われる。
最初に出現したIDについて、その情報をpb[2],pb[3]へ設定すべきと考えますがいかがでしょうか。
(get_X1.txtの1行目の遠山景晋のIDがでたらめです。ID=114795が正しいのではないでしょうか)
pb[2],pb[3]の扱いは、pb[0],pb[1]と同様です。

3.テキストの情報について
<text bytes="9434" xml:space="preserve">○○○
○○○○
○○○○</text>

のようになっているとき、○・・・・○の部分が取得対象になると理解して良いですか。
例では
○○○
○○○○
○○○○
が取得対象となる。
pb[4],pb[5]の扱いは、pb[0],pb[1]と同様です。

投稿2022/07/05 11:40

tatsu99

総合スコア5424

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

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

studyprg

2022/07/05 11:41

あってます。 ①を見るにタイトルからまちがってたんですね。
tatsu99

2022/07/05 23:43

テキストサイズが0になるデータですが、 <text bytes=....">○○○</text> のタグ自体がないことが判明しました。現在わかっているのは、以下のタイトルです。 MediaWiki:Sitenotice Portal:哲学/モックアップ Wikipedia:ウィキポータル/お知らせ Portal:鉄道/Commons/鉄道車両 Portal:食/新レイアウト案 Portal:ヨーロッパ/ニュース get_all_byte.txt及びget_X1.txtですが、 上記を除いて、テキストのあるものだけを、作成しますか。(1案) それとも、テキストサイズを0として、上記も含めて作成しますか。(2案) もし、2案なら、出力時のタイミングを変える必要があります。 1案の場合は、pb[0]~pb[5]が全て0より大きいタイミングでファイルへ出力します。 2案の場合は、一旦、pb[0]~pb[5]を出力せずに、保留し、新たなタイトルが出現したときに、 pb[0]~pb[5]を出力するようにします。 どちらの案を採用しますか。
studyprg

2022/07/06 02:09

1案でお願いします.
tatsu99

2022/07/06 02:54

1点、間違いました。 <text bytes=....">○○○</text>のタグ自体がないことではなく、 以下のようになっていました。 <text bytes="0" /> 1案で、対応します。
guest

0

freadで読み込むバージョンです。
open時のモードをバイナリーにしました。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define SIZE (256 * 1024 * 1024) 5#define MAX_REC (300000) 6typedef struct { 7 char title[256]; 8 char id[128]; 9 int pb1; 10 int pb2; 11} X1_INFO; 12int main() 13{ 14 15 int ll; 16 int i; 17 int x1_ctr = 0; 18 char *p; 19 X1_INFO *wx1; 20 char pb1[16]; 21 char pb2[16]; 22 char *line = malloc(SIZE); 23 char *title = malloc(SIZE); 24 char *id = malloc(SIZE); 25 char *text = malloc(SIZE); 26 char *stitle=malloc(SIZE); 27 X1_INFO *x1ptr = malloc(sizeof(X1_INFO)*MAX_REC); 28 if (x1ptr == NULL){ 29 printf("X1_INFO allocate error\n"); 30 return 10; 31 } 32 FILE *fp = NULL; 33 FILE *fr = NULL; 34 FILE *fr2 = NULL; 35 FILE *gt = NULL; 36 fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "rb");//大元.wiki記事 37 fr = fopen("list_history0.txt", "r"); //読み込むファイル検索文字列 38 fr2 = fopen("get_X1.txt", "r");//読み込むファイル2タイトルとidが記入 39 gt = fopen("history_0text.txt", "w"); //書き込むファイル 40 //get_X1を全て読み込む 41 while(fgets(line,SIZE,fr2) != NULL){ 42 if (x1_ctr >= MAX_REC){ 43 printf("Max Record Count Over:%d\n",MAX_REC); 44 return 10; 45 } 46 ll = strlen(line); 47 p = strtok(line,"\t\n"); 48 strcpy(title,p); 49 p = strtok(NULL,"\t\n"); 50 strcpy(id,p); 51 p = strtok(NULL,"\t\n"); 52 strcpy(pb1,p); 53 p = strtok(NULL,"\t\n"); 54 strcpy(pb2,p); 55 wx1 = x1ptr + x1_ctr; 56 strcpy(wx1->title,title); 57 strcpy(wx1->id,id); 58 wx1->pb1 = atoi(pb1); 59 wx1->pb2 = atoi(pb2); 60 x1_ctr++; 61 } 62 while(fgets(line,SIZE,fr) != NULL){ 63 ll = strlen(line); 64 if (line[ll-1] = '\n' && ll > 0) line[ll-1] = '\0'; //改行削除 65 strcpy(stitle,line); 66 printf("Stitle(検索対象)is %s.\n", stitle); 67 for (i = 0; i < x1_ctr; i++){ 68 wx1 = x1ptr + i; 69 if (strcmp(wx1->title,stitle) == 0){ 70 printf("%s is found! title:%s\n", stitle, wx1->title); 71 fseek(fp, wx1->pb1, SEEK_SET); 72 memset(text,0x00,SIZE); 73 if (wx1->pb2 > 0){ 74 fread(text,1,wx1->pb2, fp); 75 } 76 printf("%s\t%s\n%s", wx1->title, wx1->id, text); 77 break; 78 } 79 } 80 if (i == x1_ctr){ 81 printf("%s is not found!\n", stitle); 82 } 83 } 84 printf("\n\n\nprocess ok!\n\n\n"); 85 fclose(fp); 86 fclose(fr); 87 fclose(fr2); 88 fclose(gt); 89} 90

投稿2022/07/04 14:47

tatsu99

総合スコア5424

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

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

0

2022/07/04 18:49にコメントした分の回答ソースです。
細かいエラーチェックはしていません。(title,idの長さ、開始バイトオフセット、バイトサイズの数字チェック等)
xmlの読み込みはコメントにしてあります。(xmlの読み込みの確認も行っていません)

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#define SIZE (256 * 1024 * 1024) 5#define MAX_REC (300000) 6typedef struct { 7 char title[256]; 8 char id[128]; 9 int pb1; 10 int pb2; 11} X1_INFO; 12int main() 13{ 14 15 int ll; 16 int i; 17 int x1_ctr = 0; 18 char *p; 19 X1_INFO *wx1; 20 char pb1[16]; 21 char pb2[16]; 22 char *line = malloc(SIZE); 23 char *title = malloc(SIZE); 24 char *id = malloc(SIZE); 25 char *text = malloc(SIZE); 26 char *stitle=malloc(SIZE); 27 X1_INFO *x1ptr = malloc(sizeof(X1_INFO)*MAX_REC); 28 if (x1ptr == NULL){ 29 printf("X1_INFO allocate error\n"); 30 return 10; 31 } 32 FILE *fp = NULL; 33 FILE *fr = NULL; 34 FILE *fr2 = NULL; 35 FILE *gt = NULL; 36 fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r");//大元.wiki記事 37 fr = fopen("list_history0.txt", "r"); //読み込むファイル検索文字列 38 fr2 = fopen("get_X1.txt", "r");//読み込むファイル2タイトルとidが記入 39 gt = fopen("history_0text.txt", "w"); //書き込むファイル 40 //get_X1を全て読み込む 41 while(fgets(line,SIZE,fr2) != NULL){ 42 if (x1_ctr >= MAX_REC){ 43 printf("Max Record Count Over:%d\n",MAX_REC); 44 return 10; 45 } 46 ll = strlen(line); 47 p = strtok(line,"\t\n"); 48 strcpy(title,p); 49 p = strtok(NULL,"\t\n"); 50 strcpy(id,p); 51 p = strtok(NULL,"\t\n"); 52 strcpy(pb1,p); 53 p = strtok(NULL,"\t\n"); 54 strcpy(pb2,p); 55 wx1 = x1ptr + x1_ctr; 56 strcpy(wx1->title,title); 57 strcpy(wx1->id,id); 58 wx1->pb1 = atoi(pb1); 59 wx1->pb2 = atoi(pb2); 60 x1_ctr++; 61 } 62 while(fgets(line,SIZE,fr) != NULL){ 63 ll = strlen(line); 64 if (line[ll-1] = '\n' && ll > 0) line[ll-1] = '\0'; //改行削除 65 strcpy(stitle,line); 66 printf("Stitle(検索対象)is %s.\n", stitle); 67 for (i = 0; i < x1_ctr; i++){ 68 wx1 = x1ptr + i; 69 if (strcmp(wx1->title,stitle) == 0){ 70 printf("%s is found! title:%s\n", stitle, wx1->title); 71 //fseek(fp, pb[0], SEEK_SET); 72 //fgets(text, pb[1], fp); 73 //printf("%s\t%s\n%s", title, id, text); 74 break; 75 } 76 } 77 if (i == x1_ctr){ 78 printf("%s is not found!\n", stitle); 79 } 80 } 81 printf("\n\n\nprocess ok!\n\n\n"); 82 fclose(fp); 83 fclose(fr); 84 fclose(fr2); 85 fclose(gt); 86} 87

投稿2022/07/04 12:10

tatsu99

総合スコア5424

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

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

studyprg

2022/07/04 12:21

タイトルは見つけられました. 56行目あたりのpb1をpb[1]にしたらfseekも上手く動きますかね?
tatsu99

2022/07/04 12:51

fseek(fp, wx1->pb1, SEEK_SET); fgets(text, wx1->pb2+1, fp); printf("%s\t%s\n%s", wx1->title, wx1->id, text); とりあえず、上記のようにすれば良いかと思います。
tatsu99

2022/07/04 12:57

開始バイトオフセット, バイトサイズが本当に正しいかどうかをきちんと確認するの先決かと思いますが、 もし、開始バイトオフセット, バイトサイズがきちんとした値で与えられるなら、正式な読み込み方法は、 fseekの後、freadの方がよいです。そして、読み込んだデータの直後に'\0'を付加します。(ただし、バイトサイズが0の時は読み込まない)
studyprg

2022/07/04 13:55

ですね。 とりあえずベストアンサーにしますね。
studyprg

2022/07/04 14:12

これ21:51の分でやってみたんですけどtextの一部しか取得できてないみたいです. 全部取得してhistory0textに書き込みたいいんですけどどうしたらいいですかね?
tatsu99

2022/07/04 14:19

開始バイトオフセット, バイトサイズが信用できないので、textの一部しか取得できないのはどうしようもないです。textの正しいサイズが100であるにもかかわらず、get_X1.txtのバイトサイズには50と書かれている状態なので、50バイト分しか読み込めません。 なので、本当に正しい、開始バイトオフセット, バイトサイズが設定されたget_X1.txtを入手するのが先決かと思います。素朴な疑問なのですが、get_X1.txtは、どこから提供されたものなのでしょうか。
studyprg

2022/07/04 14:23

自分で作ったものですね. 共有しますね.
tatsu99

2022/07/04 14:39

まだ、wiki_parserX.cは見ていませんが、23:19のコメントに一部過ちがあったので、訂正します。 fgetsで,読み込んだ場合は、改行コードを読み込むと、そこで終了します。よって、途中までしか、読み込みません。 freadを使って読み込めば、その点は、改善する可能性があります。(開始バイトオフセット, バイトサイズが正しい前提ですが) fread版をこれから作成します。
tatsu99

2022/07/04 14:50

fread版をアップしました。 一つ目、二つ目のファイルの確認は、明日行います。
studyprg

2022/07/04 15:53

ありがとうございます よろしくお願いします
tatsu99

2022/07/04 20:58

一つ目、二つ目のファイルですが、両方とも、wiki_parserX.c になっています。 ご確認をお願いします。
guest

0

回答ではありません。
こちらでも、同じファイルを使用して、動かしてみますので、
ファイルを下記URLにアップしていただくことは可能でしょうか。
https://firestorage.jp/

下記ファイルをアップしてください。
1.list_history0.txt
2.get_X1.txt
3.jawiki-20211220-pages-articles-multistream2.xml

尚、実行時の環境(OS及びコンパイラ)も参考までに提示してください。

投稿2022/07/04 05:29

tatsu99

総合スコア5424

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

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

studyprg

2022/07/04 05:50 編集

passはいらないようです.
studyprg

2022/07/04 05:50 編集

実行環境はMacOSです.
tatsu99

2022/07/04 06:29

申し訳ありません。 jawiki-20211220-pages-articles-multistream2.xml のダウンロードを2回ほど試みたのですが、途中で終了してしまいました。 お手数ですが、一旦、このファイルをzip形式に圧縮したのち、再度アップしていただくことは可能でしょうか。 (他の2ファイルは正常にダウンロードできました)
studyprg

2022/07/04 06:31

やってみます.
tatsu99

2022/07/04 06:55

ありがとうございました。全ファイルダウンロードできました。
tatsu99

2022/07/04 07:47

>get_X1.txt の各行が (xml ファイル内の記事の ) "タイトル", "id", "開始バイトオフセット", "バイトサイズ" を示している。 ということですが、本当に"開始バイトオフセット", "バイトサイズ" なのでしょうか。 例えば、get_X1.txt の1行目は、遠山景晋 493646 2948 0 ですが、そうすると、開始バイトオフセット=2948、バイトサイズ=0となります。 実際に、 jawiki-20211220-pages-articles-multistream2.xmlをエディタで開くと、 2948バイトから記事が始まっていません。また、記事のサイズが0というのもおかしな話です。
studyprg

2022/07/04 08:25

まじですか… 前のも間違ってたっぽいですね…
studyprg

2022/07/04 08:30

タイトルだけあって中身がないのもあるのでそれだろうなとスルーしてました。
tatsu99

2022/07/04 09:13

ほかのも調べてみました。 遠山景晋 2948 0 <text bytes="9434" xml:space="preserve">{{基礎情報 武士 双子 (映画) 13316 12558 <text bytes="3405" xml:space="preserve">{{Infobox Film| 新銀行東京 91374 90824 <text bytes="51018" xml:space="preserve">{{基礎情報 会社 開始位置はxmlファイルでは、<text bytesの1つ前の位置(空白)からになっています。 バイトサイズに関しては、よくわかりません。 従って、まったくでたらめでもないようですが、期待した値でもないように思われます。
tatsu99

2022/07/04 09:19

>追記:1週したらもう一度頭から読み込み直すはずのfr2が一回だけで止まってるようです. これは、この方法でやるなら毎回オープン、クローズしないとだめですね。 通常は、一旦、内部メモリ(テーブル)に全て読み込んでから行うのが一般的です。 (ただ、その場合は事前に何行あるかがわかっているか、行の自動拡張を行い仕組みを実装する必要があります) とりあえずは、毎回、オープン、クローズする方法を回答します。
studyprg

2022/07/04 09:44

了解しました 毎回オープンクローズでできる方法で試してみます。 過去のやつについてはこれが終わってから修正します。
tatsu99

2022/07/04 09:49

すみません。現在のfscanの場合「高橋和之 (憲法学者)」のようなとき、空白が1文字あるので、 get_X1.txtをfscanfで読み込むとおかしなことになります。 list_history0.txtには現在、そのようなケースはありませんが、出現する可能性はあるので、これもやめた方が良いですね。 list_history0.txtは1行、読み込んで、改行を削除したものを採用する。 get_X1.txtは1行読み込んで、タブで分割し、各項目を取得します。 又、get_X1.txtは毎回オープン、クローズするのをやめて、一気に内部テーブルに格納します。 とりあえず、レコード件数の上限=30万件としておきます。(get_X1.txtは約12万件)
studyprg

2022/07/04 11:21

了解しました 試してみたものを追記に書き込みますね
studyprg

2022/07/04 12:13

fopen毎回するパターンで試してみましたが,同一のものがあるはずなのに見つかった処理には言ってないですね. 質問ぶんアップデートしましたんで確認お願いします.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問