自然言語処理について勉強しています。
Wikipediaのdumpデータから本文を抜き出して処理をしようと思ってます。
xmlの処理について試しているのですが、出力結果が想定とは全然違って困っています。
欲しい出力は,"タイトル(str),id(int),<textのシークポイント(*int)(<textの二つ目のtのポイント),<textから</text>の間のバイト数(*int)の四つがセットになったものです.
おそらくたくさんのif文処理で目的のところにひっかけられてないのだと思います.
以下にソースコード
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p, pb[6]; char *line = malloc(SIZE); char *title; char *id; FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); FILE *fw = fopen("getX.txt", "w"); //記入先 if ((NULL == fp) || (NULL == fw)) abort(); while (p = ftell(fp), fgets(line, SIZE, fp)) { if (strstr(line, "<title>")) { pb[0] = p; if ((strstr(line, "</title>"))) { pb[1] = p - pb[0]; pb[0] += strlen("<title>"); fseek(fp, pb[0], SEEK_SET); fgets(title, pb[1], fp); printf("%s\n", title); if (strstr(line, "<title>")) { pb[2] = p; if (strstr(line, "<id>")) { pb[2] = p; if (strstr(line, "</id>")) { pb[3] = p - pb[2]; pb[2] += strlen("<id>"); fseek(fp, pb[2], SEEK_SET); fgets(id, pb[3], fp); printf("title=\t%s\nid=\t%s\n", title, id); if (strstr(line, "<text")) { pb[4] = p; if (strstr(line, "</text>")) { pb[5] = p - pb[4]; printf("%s\t%s\t%d\t%d\n", title, id, pb[4], pb[5]); } } } } } } } } printf("process ok"); free(line); fclose(fw); fclose(fp); }
出力結果は何も表示されてないようです.急ぎです.お願いします.
追記:6/2618:00
修正依頼にあったように処理の前にprintfを追加してみたバージョンのソースと実行結果を載せておきます.
おそらく/titleの処理を忘れているのではないかなと思います.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p, pb[6]; char *line = malloc(SIZE); char *title; char *id; FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); FILE *fw = fopen("getX.txt", "w"); //記入先 if ((NULL == fp) || (NULL == fw)) abort(); while (p = ftell(fp), fgets(line, SIZE, fp)) { /* // textやpageなどの複数行にわたるとき if (strstr(line, "<text")) {//属性があるため<text pb[0] = p; } if (strstr(line, "</text>")) { pb[1] = p - pb[0]; printf("%d\t%d\n", pb[0], pb[1]); fprintf(fw, "%d\t%d\n", pb[0], pb[1]); } */ if (strstr(line, "<title>")) { printf("title in\t 1\n"); pb[0] = p; if ((strstr(line, "</title>"))) { printf("/title in\t1\n"); pb[1] = p - pb[0]; pb[0] += strlen("<title>"); fseek(fp, pb[0], SEEK_SET); fgets(title, pb[1], fp); printf("%s\n", title); if (strstr(line, "<title>")) { printf("title\tin\t22222222222\n"); pb[2] = p; if (strstr(line, "<id>")) { printf("id in\t\n"); pb[2] = p; if (strstr(line, "</id>")) { printf("/id in \n"); pb[3] = p - pb[2]; pb[2] += strlen("<id>"); fseek(fp, pb[2], SEEK_SET); fgets(id, pb[3], fp); printf("title=\t%s\nid=\t%s\n", title, id); if (strstr(line, "<text")) { printf("text in "); pb[4] = p; if (strstr(line, "</text>")) { printf("/text in "); pb[5] = p - pb[4]; printf("%s\t%s\t%d\t%d\n", title, id, pb[4], pb[5]); } } } } } } } } printf("process ok"); free(line); fclose(fw); fclose(fp); }
以下実行結果の一部です.
title in 22222222222 title in 1/title in 2(null) title in 22222222222 title in 1/title in 2(null) title in 22222222222 title in 1/title in 2(null) title in 22222222222 title in 1/title in 2(null) title in 22222222222 title in 1/title in 2(null) title in 22222222222 process ok
処理のバランスおかしいですね.
報酬はいくらくらいですか?
>おそらくたくさんのif文処理で目的のところにひっかけられてないのだと思います.
それで、何処までそれを確認されたのでしょうか。
デバッグは推理して終わりではありません。どう動くはずなのにどうなってしまったのかを推理して確認して修正することの繰り返しです。
どの様な入力でどの様な出力になるはずがどの様な出力になったのか、「出力結果が想定とは全然違って」というだけでは何も分かりません。
jimbeさん
一応コンパイルして確認はしたつもりでした。
タイトル辺りからコンパイルできて実行できはしましたが、実行結果のプリント文が何も表示されず、動いている感じはしていたのですが何も表示されず、最後のprocess okだけ表示されて終わる状態です。
zuishinさん
報酬とはなんでしょうか?
まだ使い慣れてなく、その辺わかってないです。
報酬はいくらくらいですか?
リファクタリング作業の依頼ですよね?
出力が意図通りになっていないのであれば、デバッグから行うことになりますが。
そうですね。
教えてほしいこと自体はリファクタリングで合ってると思います。
> 出力結果は何も表示されてないようです.急ぎです.お願いします.
いまだ何か勘違いされているような気がしますが、teratailは何らかの課題をぶん投げると誰かが自動的に無償で解決してくれるサービスではありません。
一応処理がこんがらがってわからないから教えてほしい的な意味合いで投稿したつもりでした。
丸投げした感じになってたら申し訳ありません
>一応コンパイルして確認はしたつもりでした。
コンパイルエラーが無くなったらもう出来ることが無い訳ではありません。
各 if の前でその条件に使っている変数を表示する printf を入れて実行してみて、思ったような値になっているか、また、if が成立/不成立した場合のコードの先頭にも (process ok のような) 目印となる printf を入れてどこを通っているか等、動作・変数の変化等様々なことを確認することも、プログラムを作るという作業の一部です。
それを徹底的に行ってなお動作がおかしいとなれば質問されるのも分かりますが、怠っていると見られれば作業依頼
と取られてしまいます。
とりあえず、入力ファイルの内容はどんななのか、どの様な表示になるはずだったのか、上記のようにあちこちに printf を入れて見たらどうなったのか等をご質問に追記して頂けますでしょうか。
想定通りに動作していないのではリファクタリングは意味が無いと思いますが。
> if文の整理をして欲しい
このタイトルから丸投げ以外のなにかを想像するのは難しいです。
「お願いします」というのは具体的に何を「お願い」しているのでしょう。
本来あなたが行うべき作業の代行として「不具合の解析・検討を行い、コピペすれば動くソースを提示せよ」という要求であれば、それはまさに丸投げと呼ばれるものです。
リファクタリングというのは、プログラム(あるいはその部分)の入力/出力は一切変更することなく、より良い構成、記法にすることを言います。今と異なる出力を要求するものはリファクタリングではありません。
jimbeさん
処理にプリント分を追加して動きを見ました.
今から質問文に追記します.
あと、objective-cのタグは関係ないと思います。タグは、あなたの質問が内容に無関係な多くの人の注目を集めるためにつけるのではなく、情報を求めている誰かがタグを使って情報を絞り込むためのものです。
thkanaさん
タグ修正しました.
あなたの過去の質問はObjective-Cに関係あるのですか?
おそらく関係ないっすね。
一応MacBookで作業してるので…
認識の違いでした。
> おそらくたくさんのif文処理で目的のところにひっかけられてないのだと思います.
ということであれば、
ifの直前で、判断しようとしている物をprintして、意図通りの内容か確認しましょう。
まず、ここの回答者はあくまで質問者と同じ単なるユーザです。
金を貰って回答しているわけではありません。
回答者は質問者の先生でもないし、部下でもありません。ましてや奴隷でもありません。
簡単に考えていますけど、こういう作業依頼は普通、金銭等の報酬が発生します。一般人からしたらたかが客の髪の毛を切るだけでも立派な仕事で報酬が発生します。時間にするとせいぜい1時間程度。もちろん本来は「たかが」ではありませんが。
ましてやプログラミングするときのデバッグってものによっては1〜2日は簡単に潰れますよ。私も軽い一括処理程度のものを作ったりしますけど、デバッグだけで数日は確実にかかっています。センスがあって簡単なものでも半日は潰れますよ。それを報酬なしでやれは暴言が過ぎますよ。それに加えて「急ぎやってくれ」的な発言があるようですが、これは適切な言葉でしょうか。
とりあえず、6/2618:00のプログラムで
title in 2(null)
と表示される要素は無いように思いますがどう考えますか?
> 自然言語処理について勉強しています。
Cで書かれていますが上記目的であればPython等の方が簡単で向いているかと思います。Cでテキスト処理は難易度が高いのではないでしょうか?
> 処理のバランスおかしいですね.
見るべきはバランスでは無く、処理順や変数値が想定通りなのかそうでないのか、そうで無いならば何が原因なのかをさらに調べることです。
ちなみに、目印の printf にスペースやタブ、改行を多く使うのは止めたほうが良いです。見た目で分かりにくくなります。
同じ文字列を使うと、どれが表示されたのかが分かりません。全ての printf に通し番号を付ける等で、"1"はココ、"5"はココ等とはっきり分かるようにし、 123...となるはずなのに 13...てなんで?となったほうが分かり易いと思います。
jawiki-20211220-pages-articles-multistream2.xml というファイルの中身を得たいのですが、どこかからダウンロード等出来ますでしょうか。
jimbeさん
> 全ての printf に通し番号を付ける
私はマクロ__LINE__を使うことが多いです。
printf("%d:data=%d\n" , __LINE__ , 覗きたいデータ);
とすると、コンパイル時に__LINE__がソースコードの行番号に置き換えられます。ソースコードとの対応も調べやすいです。ソースコードを編集すると変わっちゃいますが...
とりあえず-Wallつけてコンパイルしてみると
test.c:24:17: warning: ‘title’ may be used uninitialized in this function [-Wmaybe-uninitialized]
24 | fgets(title, pb[1], fp);
test.c:34:29: warning: ‘id’ may be used uninitialized in this function [-Wmaybe-uninitialized]
34 | fgets(id, pb[3], fp);
という警告が出ます(質問当時/6/2618:00いずれも同様)。なぜ警告になるか、このプログラムを実行するとどういう事態を引き起こすか、わかりますか?
さまざまな方からの修正依頼ありがとうございます。
指摘内容からどこを修正すれば治るのかがざっくりですがわかってまいりました。
ちなみにjimbeさんが言っていたファイルは去年の末に勉強用のデータ集めでダウンロードしたものなので今はもうないと思います
https://teratail.com/questions/1dw97rbu3hraah の追記修正依頼欄の2022/06/19 17:54投稿分がテスト用データと考えてよいですね?
であれば、インデントが影響しそうな気がすごくするので、できれば質問に追記で
```
```
で囲って貼っていただけませんか?
そして、そのデータに対して「コレと一致すればOK」という「想定する結果」を示して下さい。
(質問するならそれくらいのデータの提示をするものだというだけの話で、それで丸投げでなくなるとかいうわけじゃないですけれど)
>私はマクロ__LINE__を使うことが多いです。
(中略)
>ソースコードを編集すると変わっちゃいますが...
一時期マクロを使っていたことがありますが、ログを見ながらコードを弄っているとそれだけでズレてしまって・・・ちゃんと一つずつ修正・実行すればいいだけなんですけどね^^;
> 2022/06/26 18:00
> 認識の違いでした。
認識の「間違い」ですね。
過去の質問についても、Objective-Cが関係ないのならタグは外してください。
回答2件
あなたの回答
tips
プレビュー