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

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

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

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

C

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

Open XML

Open XMLは、マイクロソフト社が開発したオープンなXMLベースのオフィススイート用のファイル形式です。従来のバイナリ形式のフォーマットに代わって、XMLを用いた規格を標準ファイル形式として採用しています。

Q&A

解決済

1回答

533閲覧

[c]wikiのdumpデータから読み込んだ出力がおかしい

studyprg

総合スコア57

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

C

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

Open XML

Open XMLは、マイクロソフト社が開発したオープンなXMLベースのオフィススイート用のファイル形式です。従来のバイナリ形式のフォーマットに代わって、XMLを用いた規格を標準ファイル形式として採用しています。

0グッド

0クリップ

投稿2022/06/13 06:26

編集2022/06/13 08:40

やりたいこと

自然言語処理について勉強しています。
Wikipediaのdumpデータから本文を抜き出して処理をしようと思ってます。
、出力結果が想定とは全然違って困っています。
欲しい出力は,,<title>hoge</title><id>hoge</id>の中身です。(hoge部分)
後述の出力の一文字目が?になってて困っています。
プログラミングはあまり得意ではないです。

実行環境

Macbook pro(2017)
OS:11.6.7

以下に用意したファイル(<page>~~</page>)の一部とソースコードを貼り付けます。

get_text_All.txt

1 <page> 2 <title>遠山景晋</title>//ここが欲しい 3 <ns>0</ns> 4 <id>114795</id>//ここも欲しい. 5 <revision> 6 <id>86493646</id> 7 <parentid>81273289</parentid> 8 <timestamp>2021-11-12T08:36:31Z</timestamp> 9 <contributor> 10 <ip>27.85.204.9</ip> 11 </contributor> 12 <model>wikitext</model> 13 <format>text/x-wiki</format> 14 <text bytes="9434" xml:space="preserve">{{基礎情報 武士 15| 氏名 = 遠山景晋 16| 画像 = 17| 画像サイズ = 18| 画像説明 = 19| 時代 = [[江戸時代]]後期 20| 生誕 = [[宝暦]]14年[[1月14日 (旧暦)|1月14日]]([[1764年]][[2月15日]])&lt;ref&gt;本妙寺の墓碑による([[氏家幹人]]『旗本御家人―驚きの幕臣社会の真実』(洋泉社歴史新書y 2011年)72頁)。&lt;/ref&gt;&lt;ref group=&quot;†&quot;&gt;『[[寛政重修諸家譜]]』などの幕府編纂の資料では宝暦2年([[1752年]])生まれとされているが、それは[[官年]]とみられる(氏家幹人『旗本御家人―驚きの幕臣社会の真実』(洋泉社歴史新書y 2011年)72頁)。&lt;/ref&gt; 21 22 23 24 25中略 26 27 28 29 30[[Category:1837年没]]</text> 31 <sha1>chmmooepsrvwuo4n0ziki50nn5rvhj7</sha1> 32 </revision> 33 //</page>の手前までで終わっている. 34 <page>//次のページ 35... 36...

ソースコード

Wiki_getter3_title.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 = 0; 9 int b = 0; 10 int pb[5] = {}; 11 int id = 0; 12 char *idnum = malloc(SIZE); 13 char *line = malloc(SIZE); 14 char *title = malloc(SIZE); 15 FILE *fp = NULL; //読み込み 16 FILE *fw = NULL; //書き込み 17 fp = fopen("get_text_all.txt", "r"); 18 fw = fopen("get_title_id.txt", "w"); 19 if ((fp == NULL) || (fw == NULL)) 20 { 21 printf("failed load ファイル"); 22 abort(); 23 } 24 25 while (p = ftell(fp), fgets(line, BUFSIZ, fp)) 26 { 27 char *p1, *p2; 28 p1 = strstr(line, "<title>"); 29 p2 = strstr(line, "</title>"); 30 if (p1 && p2) // 1行に両方見つかった 31 { 32 b = strlen("<title>"); 33 p1 += strlen("<title>"); // <title>の次の位置 34 int len = p2 - p1; 35 if (len >= 0) 36 { 37 memcpy(title, p1, len);//これをやるべきなのか?参考までに 38 //fseek(fp, -b, SEEK_CUR); 39 //fseek(fp, p + (p1 - line), SEEK_SET); //<title>まで戻る 40 //fgets(title, len + 1, fp); //読み込んでタイトルに格納 41 title[len] = '\0'; // 終端記号を忘れずに追加 42 43 char *p3, *p4; 44 p3 = strstr(line, "<id>"); 45 p4 = strstr(line, "</id>"); 46 // frite(); 47 // fprintf(fw, "%s\n", title); 48 49 if (p3 && p4) // 1行に両方見つかった 50 { 51 b = strlen("<id>"); 52 p3 += strlen("</id>"); // <title>の次の位置 53 int len = p4 - p3; 54 if (len >= 0) 55 { 56 memcpy(idnum, p1, len);//これをやるべきなのか?参考までに 57 // fseek(fp, -b, SEEK_CUR); 58 //fseek(fp, p + (p3 - line), SEEK_SET); //<id>まで戻る 59 //fgets(idnum, len + 1, fp); //読み込んでタイトルに格納 60 idnum[len] = '\0'; // 終端記号を忘れずに追加 61 62 63 64 } 65 } 66 } 67 printf("title\tis\t%s\tID:%s\n", title, idnum); 68 fprintf(fw, "%s\t%s\n", line,idnum); 69 } 70 71 72 } 73 printf("process ok"); 74 free(line); 75 free(idnum); 76 free(title); 77 fclose(fp); 78 fclose(fw); 79} 80

エラーについて.

以下に示しますが,titleは表示されていますがidnumが表示されず,打ち消し線取得したタイトルは後半部分がおかしくなってます.
タイトルは取得できましたが,idnumが表示されてないです.

terminal

1 2最後の方を表示 3 4title is 島田洋七(ID:). 5title is 大砂土村(ID:). 6title is J級潜水艦 (イギリス海軍)(ID:). 7title is ランカウイ島(ID:). 8title is 外山雄三(ID:). 9title is 工藤順子(ID:). 10process ok

ループの終了位置をミスしているのかな?
idnumが空っぽいですね.

参考程度にget_all_textの一例と欲しい部分です。これが大量に入ったファイルが欲しいです。

get_all_text.txt

1 <page> 2 <title>鳥取砂丘</title>//ここが欲しい 3 <ns>0</ns>//ここはいらない 4 <id>19812</id>//ここも欲しい 5 <revision> 6 <id>53717095</id> 7 <parentid>53211643</parentid> 8 <timestamp>2014-12-06T03:46:16Z</timestamp> 9 <contributor> 10 <ip>58.156.158.18</ip> 11 </contributor> 12 <comment>/* 砂丘の利用と周辺住民とのかかわり */</comment> 13 <model>wikitext</model> 14 <format>text/x-wiki</format> 15 <text xml:space="preserve">{{Coord|35|32|27.821|N|134|13|41.789|E|region:JP|display=title}} 16[[ファイル:Tottori-Sakyu Tottori Japan.JPG|thumb|300px|馬の背]] 17{{mapplot|134.2290|35.5407|鳥取砂丘}} 18'''鳥取砂丘'''(とっとりさきゅう)は、[[鳥取県]][[鳥取市]]の[[日本海]]海岸に広がる広大な砂礫地で、代表的な[[海岸砂丘]]。日本三大砂丘の1つである&lt;ref&gt;その他の2つについては、諸説ある。&lt;/ref&gt;。[[山陰海岸国立公園]]の特別保護地区に指定されており、南北2.4km、東西16kmに広がる日本最大の観光可能な[[砂丘]]である。(一般に立ち入れない物も含めると、日本最大の砂丘は&lt;!--(内陸にある砂丘を含めると--&gt;[[青森県]]の[[猿ヶ森砂丘]])。&lt;!--内陸砂丘は大陸内部の砂丘を示し、日本には内陸砂丘なないため編集しました--&gt; 19 20[[1955年]](昭和30年)に国の[[天然記念物]]に指定された。[[2007年]](平成19年)には[[日本の地質百選]]に選定された。 21 22== 砂丘の状況 == 23[[中国山地]]の[[花崗岩]]質の[[岩石]]が[[風化]]し、[[千代川]]によって日本海へ流されたあと、海岸に集まったものが砂丘の主な[[砂]]となっている。海中の砂を海岸に向けて流れ寄せる潮流と、海岸線に[[堆積]]した砂を内陸へ吹き込む[[卓越風]]の働きで形成された。 24 25砂丘は千代川の東西に広がっているが、通常「鳥取砂丘」というと、千代川の東側の545haの「浜坂砂丘」を指す。砂丘によって海から切り離されて出来た湖である[[多鯰ヶ池]]がすぐ南東にある。 26 27 28<中略> 29 30 31</text> 32 <sha1>axvz6j2vrmxe3n68ssg11m0w8qtcobn</sha1> 33 </revision> 34 </page> 35 36

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

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

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

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

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

studyprg

2022/06/13 06:39

個人的にライブラリは使わない感じでやってます。 ライブラリ楽すぎるんで。
int32_t

2022/06/13 06:41

Pythonでも使ったほうが遥かに簡単に目的を達成できると思うのですけど、わざわざC言語を使うのは修行のためですか?
studyprg

2022/06/13 06:42

今までのもそうですけど修行ですね。 プログラム弱すぎって言われたんで。
int32_t

2022/06/13 09:12

1文字目が?になるという問題が解決したのなら、この質問は解決済みにして別の質問を立てませんか? あと、回答が付いたら質問中のコードは更新しないでください。新しいコードを見せたいときは新しいコードを*追加*してください。そうしないと、回答が意味不明になってしまいます。 (実際、私の回答は現在存在しないコードを引用していて、第三者が見ると意味不明です)
guest

回答1

0

ベストアンサー

c

1 fseek(fp, -b, SEEK_CUR); 2 fseek(fp, -len, SEEK_CUR); //<title>まで戻る 3 fgets(title, len - 1, fp); //読み込んでタイトルに格納

ここが間違ってますね。このコードの直前では、「line の行の直後」が現在のファイル位置になってます。直前は </title>\n などになっているでしょうから、bは関係ありません。
SEEK_CUR で移動するなら、「(p1 - line) - line の長さ」を fseek() にわたす必要があります。
SEEK_SET で移動するなら、「p + (p1 - line)」でしょうか。

fgets() の第2引数は len + 1 にします。

c

1 // memcpy(title, p1, len);//これをやるべきなのか?参考までに 2 // title[len] = '\0'; // 終端記号追加(いるのか不安)

fseek()fgets() ではなくこの2行で済むと思います。試してみましたか?

投稿2022/06/13 06:48

編集2022/06/13 06:52
int32_t

総合スコア21421

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

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

studyprg

2022/06/13 07:40

うまいこといきました!
studyprg

2022/06/13 07:44

最初はいい感じなんですけど title is 「akuchaku J.b (ID:0)」. title is 「?楽器 (ID:0)」. title is 「kipedia:削除依頼/七瀬優 (ID:0)」. title is 「?田県立男鹿水族館 (ID:0)」. title is 「tegory:反ナチ運動 (ID:0)」. title is 「?ナンケ (衛星) (ID:0)」. title is 「?ットー1世 (バイエルン王) (ID:0)」. 最後の方は title is 「 <ns>0</ns>(ID:0)」. title is 「 <ns>0</n (ID:0)」. title is 「 <ns>0</n (ID:0)」. みたいな感じでおそらく <page> <title>鳥取砂丘</title> <ns>0</ns> タイトルの下の行が読まれています. ていうか?入ってますね.
int32_t

2022/06/13 07:56

どういうコードに更新して実行したのか不明なので何とも言えないですが、 回答には3通りの方法(SEEK_CUR, SEEK_SET, memcpy())が書いてあるので、ぜんぶ試してみては。
studyprg

2022/06/13 08:08

とりあえずSEEK_SETのバージョンで試したものを更新します.
studyprg

2022/06/13 08:41

更新しました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問