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

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

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

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

Open XML

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

Q&A

解決済

2回答

992閲覧

【c】if文の整理をして欲しい

studyprg

総合スコア57

C

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

Open XML

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

0グッド

0クリップ

投稿2022/06/26 07:01

編集2022/06/27 10:18

自然言語処理について勉強しています。
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

処理のバランスおかしいですね.

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

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

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

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

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

Zuishin

2022/06/26 07:19

報酬はいくらくらいですか?
jimbe

2022/06/26 07:21

>おそらくたくさんのif文処理で目的のところにひっかけられてないのだと思います. それで、何処までそれを確認されたのでしょうか。 デバッグは推理して終わりではありません。どう動くはずなのにどうなってしまったのかを推理して確認して修正することの繰り返しです。 どの様な入力でどの様な出力になるはずがどの様な出力になったのか、「出力結果が想定とは全然違って」というだけでは何も分かりません。
studyprg

2022/06/26 07:27

jimbeさん 一応コンパイルして確認はしたつもりでした。 タイトル辺りからコンパイルできて実行できはしましたが、実行結果のプリント文が何も表示されず、動いている感じはしていたのですが何も表示されず、最後のprocess okだけ表示されて終わる状態です。
studyprg

2022/06/26 07:27

zuishinさん 報酬とはなんでしょうか? まだ使い慣れてなく、その辺わかってないです。
Zuishin

2022/06/26 07:28

報酬はいくらくらいですか?
Zuishin

2022/06/26 07:29 編集

リファクタリング作業の依頼ですよね? 出力が意図通りになっていないのであれば、デバッグから行うことになりますが。
studyprg

2022/06/26 07:30

そうですね。 教えてほしいこと自体はリファクタリングで合ってると思います。
dodox86

2022/06/26 07:38

> 出力結果は何も表示されてないようです.急ぎです.お願いします. いまだ何か勘違いされているような気がしますが、teratailは何らかの課題をぶん投げると誰かが自動的に無償で解決してくれるサービスではありません。
studyprg

2022/06/26 07:47

一応処理がこんがらがってわからないから教えてほしい的な意味合いで投稿したつもりでした。 丸投げした感じになってたら申し訳ありません
jimbe

2022/06/26 07:51

>一応コンパイルして確認はしたつもりでした。 コンパイルエラーが無くなったらもう出来ることが無い訳ではありません。 各 if の前でその条件に使っている変数を表示する printf を入れて実行してみて、思ったような値になっているか、また、if が成立/不成立した場合のコードの先頭にも (process ok のような) 目印となる printf を入れてどこを通っているか等、動作・変数の変化等様々なことを確認することも、プログラムを作るという作業の一部です。 それを徹底的に行ってなお動作がおかしいとなれば質問されるのも分かりますが、怠っていると見られれば作業依頼 と取られてしまいます。 とりあえず、入力ファイルの内容はどんななのか、どの様な表示になるはずだったのか、上記のようにあちこちに printf を入れて見たらどうなったのか等をご質問に追記して頂けますでしょうか。
jimbe

2022/06/26 07:53

想定通りに動作していないのではリファクタリングは意味が無いと思いますが。
thkana

2022/06/26 08:24

> if文の整理をして欲しい このタイトルから丸投げ以外のなにかを想像するのは難しいです。 「お願いします」というのは具体的に何を「お願い」しているのでしょう。 本来あなたが行うべき作業の代行として「不具合の解析・検討を行い、コピペすれば動くソースを提示せよ」という要求であれば、それはまさに丸投げと呼ばれるものです。 リファクタリングというのは、プログラム(あるいはその部分)の入力/出力は一切変更することなく、より良い構成、記法にすることを言います。今と異なる出力を要求するものはリファクタリングではありません。
studyprg

2022/06/26 08:31

jimbeさん 処理にプリント分を追加して動きを見ました. 今から質問文に追記します.
thkana

2022/06/26 08:34

あと、objective-cのタグは関係ないと思います。タグは、あなたの質問が内容に無関係な多くの人の注目を集めるためにつけるのではなく、情報を求めている誰かがタグを使って情報を絞り込むためのものです。
studyprg

2022/06/26 08:36

thkanaさん タグ修正しました.
thkana

2022/06/26 08:48

あなたの過去の質問はObjective-Cに関係あるのですか?
studyprg

2022/06/26 09:00

おそらく関係ないっすね。 一応MacBookで作業してるので… 認識の違いでした。
otn

2022/06/26 09:05 編集

> おそらくたくさんのif文処理で目的のところにひっかけられてないのだと思います. ということであれば、 ifの直前で、判断しようとしている物をprintして、意図通りの内容か確認しましょう。
BeatStar

2022/06/26 09:05

まず、ここの回答者はあくまで質問者と同じ単なるユーザです。 金を貰って回答しているわけではありません。 回答者は質問者の先生でもないし、部下でもありません。ましてや奴隷でもありません。 簡単に考えていますけど、こういう作業依頼は普通、金銭等の報酬が発生します。一般人からしたらたかが客の髪の毛を切るだけでも立派な仕事で報酬が発生します。時間にするとせいぜい1時間程度。もちろん本来は「たかが」ではありませんが。 ましてやプログラミングするときのデバッグってものによっては1〜2日は簡単に潰れますよ。私も軽い一括処理程度のものを作ったりしますけど、デバッグだけで数日は確実にかかっています。センスがあって簡単なものでも半日は潰れますよ。それを報酬なしでやれは暴言が過ぎますよ。それに加えて「急ぎやってくれ」的な発言があるようですが、これは適切な言葉でしょうか。
thkana

2022/06/26 09:12

とりあえず、6/2618:00のプログラムで title in 2(null) と表示される要素は無いように思いますがどう考えますか?
meg_

2022/06/26 09:21

> 自然言語処理について勉強しています。 Cで書かれていますが上記目的であればPython等の方が簡単で向いているかと思います。Cでテキスト処理は難易度が高いのではないでしょうか?
jimbe

2022/06/26 09:22

> 処理のバランスおかしいですね. 見るべきはバランスでは無く、処理順や変数値が想定通りなのかそうでないのか、そうで無いならば何が原因なのかをさらに調べることです。 ちなみに、目印の printf にスペースやタブ、改行を多く使うのは止めたほうが良いです。見た目で分かりにくくなります。 同じ文字列を使うと、どれが表示されたのかが分かりません。全ての printf に通し番号を付ける等で、"1"はココ、"5"はココ等とはっきり分かるようにし、 123...となるはずなのに 13...てなんで?となったほうが分かり易いと思います。 jawiki-20211220-pages-articles-multistream2.xml というファイルの中身を得たいのですが、どこかからダウンロード等出来ますでしょうか。
thkana

2022/06/26 09:31

jimbeさん > 全ての printf に通し番号を付ける 私はマクロ__LINE__を使うことが多いです。 printf("%d:data=%d\n" , __LINE__ , 覗きたいデータ); とすると、コンパイル時に__LINE__がソースコードの行番号に置き換えられます。ソースコードとの対応も調べやすいです。ソースコードを編集すると変わっちゃいますが...
thkana

2022/06/26 09:41

とりあえず-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いずれも同様)。なぜ警告になるか、このプログラムを実行するとどういう事態を引き起こすか、わかりますか?
studyprg

2022/06/26 09:41

さまざまな方からの修正依頼ありがとうございます。 指摘内容からどこを修正すれば治るのかがざっくりですがわかってまいりました。 ちなみにjimbeさんが言っていたファイルは去年の末に勉強用のデータ集めでダウンロードしたものなので今はもうないと思います
thkana

2022/06/26 09:54 編集

https://teratail.com/questions/1dw97rbu3hraah の追記修正依頼欄の2022/06/19 17:54投稿分がテスト用データと考えてよいですね? であれば、インデントが影響しそうな気がすごくするので、できれば質問に追記で ``` ``` で囲って貼っていただけませんか? そして、そのデータに対して「コレと一致すればOK」という「想定する結果」を示して下さい。 (質問するならそれくらいのデータの提示をするものだというだけの話で、それで丸投げでなくなるとかいうわけじゃないですけれど)
jimbe

2022/06/26 13:02

>私はマクロ__LINE__を使うことが多いです。 (中略) >ソースコードを編集すると変わっちゃいますが... 一時期マクロを使っていたことがありますが、ログを見ながらコードを弄っているとそれだけでズレてしまって・・・ちゃんと一つずつ修正・実行すればいいだけなんですけどね^^;
thkana

2022/06/26 13:24

> 2022/06/26 18:00 > 認識の違いでした。 認識の「間違い」ですね。 過去の質問についても、Objective-Cが関係ないのならタグは外してください。
guest

回答2

0

ベストアンサー

外部ライブラリを使わない前提でソレっぽくやるなら正規表現だろうということで、ファイルを全部読み込んでから title や id を探すようにしてみました。
テストデータとして jawiki-20211220-pages-articles-multistream2.xml には https://teratail.com/questions/jpe7mn08n0cpz7 の鳥取砂丘のデータを入れました。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <sys/types.h> 5#include <sys/stat.h> 6#include <fcntl.h> 7#include <unistd.h> 8#include <errno.h> 9#include <regex.h> 10 11long getFileSize(char *filename) { 12 int fd = open(filename, O_RDONLY); 13 if(fd == -1) { 14 fprintf(stderr, "open error. errno=%d, filname=%s\n", errno, filename); 15 return -1L; 16 } 17 18 struct stat stbuf; 19 if(fstat(fd, &stbuf) == -1) { 20 fprintf(stderr, "fstat error. errno=%d\n", errno); 21 close(fd); 22 return -2L; 23 } 24 25 close(fd); 26 27 return stbuf.st_size; 28} 29 30char *readFile(char *filename) { 31 long size = getFileSize(filename); 32 if(size < 0L) return NULL; 33 34 char *buf = malloc(size + 1); 35 if(buf == NULL) { 36 fprintf(stderr, "malloc error. errno=%d, size=%ld\n", errno, size); 37 return NULL; 38 } 39 40 FILE *fp = fopen(filename, "r"); 41 if(fp == NULL) { 42 fprintf(stderr, "fopen error. errno=%d, filname=%s\n", errno, filename); 43 return NULL; 44 } 45 46 if(fread(buf, size, 1, fp) < 1) { 47 fprintf(stderr, "fread error. errno=%d\n", errno); 48 fclose(fp); 49 free(buf); 50 return NULL; 51 } 52 buf[size] = '\0'; 53 54 fclose(fp); 55 56 return buf; 57} 58 59int regex(char *pattern, char *target, void (*process)(char *, regex_t *, regmatch_t *)) { 60 regex_t reg; 61 memset(&reg, 0, sizeof(regex_t)); 62 if(regcomp(&reg, pattern, REG_EXTENDED)) { 63 fprintf(stderr, "regcomp error. pattern=%s\n", pattern); 64 return -1; 65 } 66 67 int size = sizeof(regmatch_t) * (reg.re_nsub + 1); 68 regmatch_t *match = malloc(size); 69 if(match == NULL) { 70 fprintf(stderr, "malloc error. size=%d\n", size); 71 regfree(&reg); 72 return -1; 73 } 74 75 int err_code; 76 char err_msg[128]; 77 memset(err_msg, '\0', sizeof(err_msg)); 78 if((err_code = regexec(&reg, target, reg.re_nsub + 1, match, 0))) { 79 regerror(err_code, &reg, err_msg, sizeof(err_msg)); 80 fprintf(stderr, "%s: %s\n", __func__, err_msg); 81 free(match); 82 regfree(&reg); 83 return -1; 84 } 85 86 process(target, &reg, match); 87 88 free(match); 89 regfree(&reg); 90 return 0; 91} 92 93#define TITLE_MAX 128 94#define TEXTATTR_MAX 1024 95#define TEXT_MAX 8192 96 97char title[TITLE_MAX + 1] = { 0 }; 98int id = -1; 99char textAttr[TEXTATTR_MAX + 1] = { 0 }; 100char text[TEXT_MAX + 1] = { 0 }; 101 102void extractString(char *buf, int size, char *target, int so, int eo) { 103 if(so != -1 && eo != -1) { 104 int len = eo-so < size ? eo-so : size; 105 memcpy(buf, &target[so], len); 106 buf[len] = '\0'; 107 } 108} 109 110void titleProcess(char *target, regex_t *regex, regmatch_t *match) { 111 match++; 112 extractString(title, TITLE_MAX, target, match->rm_so, match->rm_eo); 113} 114 115void idProcess(char *target, regex_t *regex, regmatch_t *match) { 116 match++; 117 if(match->rm_so != -1 && match->rm_eo != -1) { 118 id = (int)strtol(&target[match->rm_so], NULL, 10); 119 } 120} 121 122void textProcess(char *target, regex_t *regex, regmatch_t *match) { 123 match += 2; 124 extractString(textAttr, TEXTATTR_MAX, target, match->rm_so, match->rm_eo); 125 match ++; 126 extractString(text, TEXT_MAX, target, match->rm_so, match->rm_eo); 127} 128 129int main() { 130 char *buf = readFile("jawiki-20211220-pages-articles-multistream2.xml"); 131 if(buf == NULL) return 1; 132 133 regex("<title>(.*)</title>", buf, titleProcess); 134 135 regex("<id>([0-9]+)</id>", buf, idProcess); 136 137 regex("<text( +([^>]*))>(.*)</text>", buf, textProcess); 138 139 printf("title='%s'\n", title); 140 printf("id=%d\n", id); 141 printf("textAttr='%s'\n", textAttr); 142 printf("text='%s'\n", text); 143 144 free(buf); 145}

実行結果

plain

1title='鳥取砂丘' 2id=19812 3textAttr='xml:space="preserve"' 4text='{{Coord|35|32|27.821|N|134|13|41.789|E|region:JP|display=title}} 5[[ファイル:Tottori-Sakyu Tottori Japan.JPG|thumb|300px|馬の背]] 6{{mapplot|134.2290|35.5407|鳥取砂丘}} 7'''鳥取砂丘'''(とっとりさきゅう)は、[[鳥取県]][[鳥取市]]の[[日本海]]海岸に広がる広大な砂礫地で、代表的な[[海岸砂丘]]。日本三大砂丘の1つである&lt;ref&gt;その他の2つについては、諸説ある。&lt;/ref&gt;。[[山陰海岸国立公園]]の特別保護地区に指定されており、南北2.4km、東西16kmに広がる日本最大の観光可能な[[砂丘]]である。(一般に立ち入れない物も含めると、日本最大の砂丘は&lt;!--(内陸にある砂丘を含めると--&gt;[[青森県]]の[[猿ヶ森砂丘]])。&lt;!--内陸砂丘は大陸内部の砂丘を示し、日本には内陸砂丘なないため編集しました--&gt; 8<中略> 9[[Category:日本の海岸景勝地]] 10[[Category:砂丘]] 11[[Category:平成百景]] 12[[Category:日本の地質百選]]'

投稿2022/06/26 12:57

jimbe

総合スコア12479

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

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

0

指摘が多すぎて整理しきれないので1から書き直したらうまいこといきました.
修正依頼してくれた方,ありがとうございました.

投稿2022/06/26 12:24

編集2022/06/26 12:26
studyprg

総合スコア57

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

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

thkana

2022/06/26 13:21

書き直したコードを提示してください。 タグの話と同様ですが、ここに相談を持ちかけた以上、もはや「解決」というのは「あなたが欲しい物を得る」ことだけではなくて、「その解決方法を共有する」ことまで含むようになっています。 https://teratail.com/tour の冒頭にも書かれています。 「質問・回答によって生まれたコンテンツを、同じ問題を持った人に最適な形で届けます。」 このコンセプトに同意した上でteratailに参加し、投稿されているものと思います。
dodox86

2022/06/27 01:18

これはまたひどい顛末ですね。閲覧、回答された方々、誰のメリットも無い。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問