- ベストアンサー
【c言語】テキストファイルからバイト数を算出したい
- 自然言語処理について勉強しています。Wikipediaのdumpデータから本文を抜き出して処理をしようと思っています。xmlの処理について試しているのですが、欲しい出力は,,<title>~~</title>のシークポイント(pb[0])と〜〜部分のバイト数(pb[1])の記入されたファイルです.
- プログラミング構成: jawiki-20211220-pages-articles-multistream2.xml(読み込み先のテキストファイル), Wiki_getter1_Byte.c(バイト数を算出するプログラム,<Page>〜〜</page>間は取得できています), Wikigetter2_text.c(getter1の出力ファイル(get_text_Byte.txt系列)からシークポイントまでfseekしてバイト数分freadしてテキストファイルに記入上と同じくページ全体とテキスト部分が取得できています)。
- 読み取ったシークポイントとバイトからxmlを抽出するプログラムは既にできているのでこの出力が正しくできるようになりたいです.よく言われますが外部ライブラリは利用しない方向でお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>具体的にはどのようにしたらアンサーの問題を解決できますか? 他の人も指摘しているとおり、まずは実際に実行したプログラムを補足に貼ってください。手入力し直すのではなく、コピー&ペーストを使ってください。 >pb[1] = p-pb[0]; <page>と</page>が同じ行に書かれていた場合はpとpb[0]の値が同じですから、引き算するとpb[1]の値は0になります。 <page>や</page>が現れた行内の位置を考慮する必要がありそうです。 最後に、単なる書き間違いだと思いますけど、プログラムでは<page>タグを調べようとしているのに、質問文では >欲しい出力は,,<title>~~</title>のシークポイント(pb[0])と〜〜部分のバイト数(pb[1])の記入されたファイルです. と書かれていますね。
その他の回答 (5)
- _kappe_
- ベストアンサー率68% (1583/2308)
チェックするタグが<title>や<page>から今度は<text>に変わっています。他意はないのでしょうけれど、いい加減だなという印象を受けます。 とりあえず<text>ということにして、入力データの仕様を確認させてください。下記のパターンのうちのどれですか。 [A]<text>〜</text>は必ず同じ行内に現れる [A']同じ行内に<text>〜</text>が複数回現れることがありえる [B]<text>と対応する</text>は必ず別の行に現れる [C]<text>と対応する</text>は同じ行に現れることも別の行に現れることもある [A]の場合は、今貼られているプログラムのpb[0]やpb[1]の計算方法を変えれば対応できそうです。しかし、それ以外の場合はpb[0]やpb[1]の計算方法だけでなく他の部分も変える必要があります。
- wormhole
- ベストアンサー率28% (1626/5665)
「<title>~~</title>のシークポイント」というのは、 「<title>」の先頭の「<」の前の時点のシークポイントの意味ですか? とりあえずは、fgets(line, SIZE, fp)で読み込まれたlineが ________<title>~~~~</title> だった場合、p,pb[0],pb[1]はどう設定されるのか考えてみてください。
- wormhole
- ベストアンサー率28% (1626/5665)
fgets(line, SIZE, fp) で読み込んだlineの中に"<page>"と"</page>"が両方存在する場合には、その結果は別段おかしくないコードになっていますけど? C言語は変数定義しただけでは初期化まではやってくれないので pb[1]が設定されていないならpb[1]が0で出力される可能性は限りなく低いので >pb[1] = pーpb[0]; で設定はされているはずです。 後は#2の方も書かれていますが、質問に書いているコード写し間違えしていませんか?{}の数もあっていないですし。
補足
編集はできなそうなので正式なソースコードをここに貼ります. ================ #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p, pb[2]; char *line = malloc(SIZE); FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); FILE *fw = fopen("get_text_byte.txt", "w"); // printf(fw,"startbyte\t記事のbyte \n"); if ((NULL == fp) || (NULL == fw)) abort(); while (p = ftell(fp), fgets(line, SIZE, fp)) { if (strstr(line, "<text")) { pb[0] = p; if (strstr(line, "</text>")) { pb[1] = p-pb[0]; } // fprintf(fw, "%zu\t%zu\n", pb[0], pb[1]); // ... // fprintf(fw, "%d\t%d\n", pb[0], pb[1]); ... テキスト形式で観察可能 } printf("%d\t%d\n", pb[0], pb[1]); } printf("process ok"); free(line); fclose(fw); fclose(fp); }
- asuncion
- ベストアンサー率33% (2127/6289)
>pb[1] = pーpb[0]; ここの引き算がどうしても全角にしか見えないのですが、 持っているソースコードは「正確に」ここにアップされた物と同じですか?
補足
編集はできなそうなので正式なソースコードをここに貼ります. ================ #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p, pb[2]; char *line = malloc(SIZE); FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); FILE *fw = fopen("get_text_byte.txt", "w"); // printf(fw,"startbyte\t記事のbyte \n"); if ((NULL == fp) || (NULL == fw)) abort(); while (p = ftell(fp), fgets(line, SIZE, fp)) { if (strstr(line, "<text")) { pb[0] = p; if (strstr(line, "</text>")) { pb[1] = p-pb[0]; } // fprintf(fw, "%zu\t%zu\n", pb[0], pb[1]); // ... // fprintf(fw, "%d\t%d\n", pb[0], pb[1]); ... テキスト形式で観察可能 } printf("%d\t%d\n", pb[0], pb[1]); } printf("process ok"); free(line); fclose(fw); fclose(fp); }
- _kappe_
- ベストアンサー率68% (1583/2308)
fgets()は行単位でデータを読み込みます。 質問文にあるプログラムの書き方だと、if (strstr(line, "</page>"))のチェックはその前のif (strstr(line, "<page>"))が成功したlineに対してだけ行われます。つまり、<page>と</page>が別の行に置かれているデータの場合、pb[1]がセットされることはありません。
補足
わかりやすい解答ありがとうございます。 具体的にはどのようにしたらアンサーの問題を解決できますか?
補足
編集はできなそうなので正式なソースコードをここに貼ります. ================ #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 256 * 1024 * 1024 int main() { int p, pb[2]; char *line = malloc(SIZE); FILE *fp = fopen("jawiki-20211220-pages-articles-multistream2.xml", "r"); FILE *fw = fopen("get_text_byte.txt", "w"); // printf(fw,"startbyte\t記事のbyte \n"); if ((NULL == fp) || (NULL == fw)) abort(); while (p = ftell(fp), fgets(line, SIZE, fp)) { if (strstr(line, "<text")) { pb[0] = p; if (strstr(line, "</text>")) { pb[1] = p-pb[0]; } // fprintf(fw, "%zu\t%zu\n", pb[0], pb[1]); // ... // fprintf(fw, "%d\t%d\n", pb[0], pb[1]); ... テキスト形式で観察可能 } printf("%d\t%d\n", pb[0], pb[1]); } printf("process ok"); free(line); fclose(fw); fclose(fp); }