gooID利用規約 改定のお知らせ

C言語初心者なのですが、
C言語で与えられたファイルの一部だけを抽出する方法を教えて頂けませんでしょうか?

たとえば、下のようなxmlファイルがあったとして
------------------------------------------
<person>
<id>20</id>
<name>watanabe</name> <score>68</score>
</person>
<person>
<id>21</id>
<name>sato</name>
</person>
<person>
<id>22</id>
<name>yoshida</name> <score>49</score>
</person>
<person>
<id>23</id>
<name>yamada</name> <score>87</score>
</person>
(以下省略)
----------------------------------
このxmlファイルから、

20 watanabe 90
21 sato
22 yoshida 49
23 yamada 87

のように数字や名前だけを抽出したデータファイルを作りたいのですが、
C言語でこんなことってできるんですか?
(できたら上の例のようにsatoさんのscoreは空欄であるような場合にも
対応できたらいいのですが。)

どなたか教えて頂けませんでしょうか?宜しくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

C言語のプログラムでXMLを読むなら、expatやlibxmlを使うのが普通だと思います。


http://expat.sourceforge.net/
http://xmlsoft.org/

"サンプル"や"使い方"をつけて検索すると使用例や解説ページが見つかると思います。


C言語でできますが、自分だったら特別な理由がない限りC言語でプログラムを書かないでしょう。
    • good
    • 0

#include<stdio.h>


int main(){
int c;
int a;

a=0;
while((c=getchar())!=EOF){
if(c=='<') a=1;
if(a==0) printf("%c",c);
if(c=='>') a=0;
}

return(0);
}

結果はこんな感じ

20
watanabe 68


21
sato


22
yoshida 49


23
yamada 87
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2014/07/16 11:22

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語でファイルから特定の文字を抽出

現在C言語でプログラム開発しています。
文字列が並んだテキストファイルから特定の部分のみを抽出したいのですが、うまくいきません。
お力を貸していただけないでしょうか。

テキストファイルの構造はこんな感じです。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
文字列

文字列

文字列badresult=*****文字列badresult=*****文字列badresult=*****文字列result=*****

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

これが10セット程記述されたファイルです。
ここから全てのbadresultの数値とresultの数値を抽出したいのです。
私が現段階で作成したプログラムがこちらです。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXLINE 2084

int main(void){
FILE *fp;
char line[MAXLINE];
char s1[]="badresult";
char s2[]="result=";
char *r;


if ((fp = fopen( "テキストファイルへのダイレクトパス", "r" )) == NULL){
printf("エラーメッセージB\n");
exit(1);
}


while (fgets(line, MAXLINE, fp) != NULL){
if(strstr(line,s1)!=NULL){
printf("%.27s",strstr(line, s1),"\n");
printf(" ");

printf(strstr(line, s2));
}

}
}

ですがこれだと1行に全てのbadresultが含まれているため、結果は
-----------------------------
badresult=***** result=******
-----------------------------

とbadresultは1つしか出てきません。
strstrのポインタをどうにかできないかと考えたのですが、
私のC言語の知識も浅いためなかなかうまくできません。
Cプログラミングに精通している方、どうか改善策を教えていただけないでしょうか。
できればなるべく簡単な方法ですと助かります。

現在C言語でプログラム開発しています。
文字列が並んだテキストファイルから特定の部分のみを抽出したいのですが、うまくいきません。
お力を貸していただけないでしょうか。

テキストファイルの構造はこんな感じです。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
文字列

文字列

文字列badresult=*****文字列badresult=*****文字列badresult=*****文字列result=*****

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

これ...続きを読む

Aベストアンサー

すでにツッコミ入ってるので気付いておられるかもですが、

> 私のやり方が悪いのでしょうか?

です。私のは最大でも 27 文字分しか一度に足しません。単純に r += 27 としなかったのは、行末とフォーマットの曖昧さを考えての保険です。

> 例が悪かったですね。実際のファイルですとbadresultはSCT、
> resultはACTというものなので一致はしないんです。

伏せ字にするのはかまいませんが、文字数や字種などは「そのまま」を提示しないと、話になりません。もっと融通のきくスクリプト言語とかならそうでもないですけどね。

Qファイルの特定行の抽出

C++言語についての質問です。

C++を利用して下記の処理を考えています。

下記のようなテキストファイルから、「名前」で始まる行だけを
抽出して、別のテキストファイへ書き込みを行います。
また、その際に”「名前」の表記”+”スペース文字”は削除します。

-----------------
住所 東京都
名前 AAAAA
年齢 15才
-----------------
住所 神奈川県
名前 BBBBB
年齢 20才
-----------------
<略>

実行後に出力されるテキストファイルには、

AAAAA
BBBBB

と記載されるように処理を行いたいです。

初心者のため、実現可能かも分かっていません・・。
お手数ですが、アドバイスをお願いします。

具体的な方法についても記載して頂けると助かります。

よろしくお願いします。

Aベストアンサー

No4です(改修←早っ、おちつけ年寄り)。
>また、その際に”「名前」の表記”+”スペース文字”は削除します。

スペース文字として、「半角または全角の1つ」としました。

while( NULL != fgets( cBuf, 255, fp1 ) ){

if( strstr( cBuf, "名前 " ) ) fprintf( fp2, "%s", &cBuf[5] );
if( strstr( cBuf, "名前 " ) ) fprintf( fp2, "%s", &cBuf[6] );
}
こんなのじゃあ質問しないか簡単すぎて・・・。C++に書き換えろ、ということかなぁ(ご質問主旨に沿っていないのではと不安)。
No1回答者さんがいわれるように「がんばって」なくて申し訳ない。

QC言語での文字列取得についてです。

 いつもお世話になっております。

 例えば、"AAA=C:\aabbcc\ddd"のような文字列があります。C言語だと、この文字列の"C:\aabbcc\"部分だけ抜き出す方法がわかりません。

 すいませんが、教えてください。

 

Aベストアンサー

今時string型を使わないでプログラムを組むのは時間の無駄です
これは最近のほとんどのC/C++コンパイラで使えます
char s[256]に問題の文字列が入っているとします

#include <string>
#include <iostream>
using namespace std;

void main(void)
{
chars[256];
stringstr;

strcpy(s,"AAA=C:\\aabbcc\\ddd");cout<<s<<endl<<endl;
str=s;
cout<<"前の削除"<<endl;
str.erase(0,str.find('=')+1);
cout<<str<<endl;
cout<<"後の削除"<<endl;
str.erase(str.find_last_of('\\')+1);
cout<<str<<endl;
}

結果:

AAA=C:\aabbcc\ddd

前の削除
C:\aabbcc\ddd
後の削除
C:\aabbcc\

なおリンクの無償ボーランドC++5.5でやりました

参考URL:http://www.borland.co.jp/cppbuilder/freecompiler/

今時string型を使わないでプログラムを組むのは時間の無駄です
これは最近のほとんどのC/C++コンパイラで使えます
char s[256]に問題の文字列が入っているとします

#include <string>
#include <iostream>
using namespace std;

void main(void)
{
chars[256];
stringstr;

strcpy(s,"AAA=C:\\aabbcc\\ddd");cout<<s<<endl<<endl;
str=s;
cout<<"前の削除"<<endl;
str.erase(0,str.find('=')+1);
cout<<str<<endl;
cout<<"後の削除"<<endl;
str.erase(str.find_last_...続きを読む

QC言語 ファイルの指定された行を表示

こんにちは。
回答お願いします。
今私は作業の高効率化を目指すためプログラムを考えています。
まだぜんぜんできていませんが・・
ファイルの指定された行を表示する関数がないだろうか?
もしくは似たような方法はないだろうかと考えています。

できれば例題とともに教えていただければ幸いです。
具体的にどういう風にしたいのかというと
----test.txt-------
aaaa
bbbbb
cccccc
dddd
eeeeeeee
ffffff
-------------------
というファイルがあったとしたらgetsで4と入れてやったら
四行目のddddが表示されるようにしたいのです。
まだまだ初心者ですのでさっと考えることができません。
どうかご教授お願いします。

Aベストアンサー

★高効率を目指しているの?
・固定長データなら高効率で1行を取得できたりします。
 例えば
 ----test.txt-------
 aaaaa
 bbbbb
 ccccc
 ddddd
 eeeee
 fffff
 -------------------
 という固定長データ(5文字×6行)の場合は
 int no = 4; ←4行目を取得したい時
 fseek( fp, ((no - 1) * 7), SEEK_SET ); ←5文字+\r+\n=『7』
 fgets( buff, sizeof(buff), fp );
 ↑
 これなら行番号で指定した1行を fgets() 関数で取得可能です。
 ※なおバイナリモードでオープンして下さい。
・可変長データの場合は行の先頭のオフセット位置を最初の読み込みで管理します。
 例えば
 ----test.txt-------
 aaaa
 bbbbb
 cccccc
 dddd
 eeeeeeee
 ffffff
 -------------------
 という可変長データ(4,5,6,4,8,6文字)の場合は
 オフセット位置の配列を行数分用意します。→事前に分かれば楽ですね。行数。
 long offset[ 100 ]; ←100行だと仮定
 int max;
 
 for ( max = 0 ; !feof(fp) ; max++ ){
  if ( max >= 100 ){ ←安全対策
   break;
  }
  offset[ max ] = ftell( fp );
  fgets( buff, sizeof(buff), fp );
 }
 ↑
 ここまでがオフセット位置の読み込みです。次は読み出しです。
 int no = 4; ←4行目を取得したい時
 fseek( fp, offset[no - 1], SEEK_SET );
 fgets( buff, sizeof(buff), fp );
 ↑
 これで行番号で指定した1行を fgets() 関数で取得可能です。
 ※やっぱりバイナリモードでオープンして下さい。
・あと行数の指定時に 1~max の範囲になるように補正処理も入れたほうが良いかも。
 例えば
 if ( no < 1 ){
  no = 1;
 }
 else if ( no >= max ){
  no = max;
 }
 ↑
 こんな感じで。
・以上を参考にして下さい。
 下の『参考URL』もどうぞ。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/fseek.html

★高効率を目指しているの?
・固定長データなら高効率で1行を取得できたりします。
 例えば
 ----test.txt-------
 aaaaa
 bbbbb
 ccccc
 ddddd
 eeeee
 fffff
 -------------------
 という固定長データ(5文字×6行)の場合は
 int no = 4; ←4行目を取得したい時
 fseek( fp, ((no - 1) * 7), SEEK_SET ); ←5文字+\r+\n=『7』
 fgets( buff, sizeof(buff), fp );
 ↑
 これなら行番号で指定した1行を fgets() 関数で取得可能です。
 ※なおバイナリモードでオープンして下さ...続きを読む

Q数値のみ抽出(C言語)

プログラムに数値を読み込ませるため数値を抽出したいのですが、初心者でありわかりませんでした。
調べてみると数値のみ抽出は可能なようなのですが、以下のような抽出は可能でしょうか?

(351.0,242.0)=33847 (347.9,241.7)= 0
(251.0,126.0)=30682 ( -1.0, -1.0)= -5
(409.0,247.0)=30336 (405.9,246.5)= 0
           ・
           ・
           ・
このうち1行目ならば
351.0 242.0 347.9 241.7
のようにかっこの中のみ(カンマ含まず)抽出させたいです。
ご存じの方よろしくお願いいたします。

Aベストアンサー

失礼 m(_ _)m
テレビ見ながら回答書いていたら、間違えて回答をクリックしてしまいました。




/* data.txt ファイルを読み込み
buff[]の内容を左詰めでまとめる1回答例

----- 実行結果 -----
351.0 242.0 347.9 241.7
251.0 126.0 -1.0 -1.0
409.0 247.0 405.9 246.5
*/
#include <stdio.h>
char *str_token(char *);

int main(void)
{
FILE *fp;
char buff[128];
if((fp=fopen("data.txt","r"))!=NULL){
while(fgets(buff, 128, fp)!=NULL){
printf("%s\n", str_token(buff));
}
fclose(fp);
}
return 0;
}


char *str_token(char *p)
{
char *t, *remember;
t = remember = p;
while(*p++ != '(');
while(*p != ')' ) *t++ = (*p++ != ',') ? *(p - 1) : ' ';
*t++ = ' ';
while(*p++ != '(');
while(*p != ')' ) *t++ = (*p++ != ',') ? *(p - 1) : ' ';
*t = '\0';
return remember;
}

失礼 m(_ _)m
テレビ見ながら回答書いていたら、間違えて回答をクリックしてしまいました。




/* data.txt ファイルを読み込み
buff[]の内容を左詰めでまとめる1回答例

----- 実行結果 -----
351.0 242.0 347.9 241.7
251.0 126.0 -1.0 -1.0
409.0 247.0 405.9 246.5
*/
#include <stdio.h>
char *str_token(char *);

int main(void)
{
FILE *fp;
char buff[128];
if((fp=fopen("data.txt","r"))!=NULL){
while(fgets(buff, 128, fp)!=NULL){
printf("%s\n", str_token(buff));
}
fclose(fp);
}
return 0;
}...続きを読む

Qバッファとは何ですか

C言語を使用してるとバッファという言葉がよく出てきますがバッファとは何ですか
メモリとは違うものですか
訳をみても緩衝材とか一時的に蓄える場所という意味でよく分かりません
一時的でない使い方も多い気がしますが実際はどういうものですか

Aベストアンサー

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速度の差のための緩衝材的な意味です。

昔はソフトウェアとハードウェア間に使うデータでソフトウェア側がデータを受け取るか、整形して送信するときに使うメモリ領域が基本的にバッファでした。
マルチプロセッサ・マルチタスクの時代になってくると、ソフトウェア間の処理速度の違いを吸収するために使うメモリ領域にもバッファという言葉が使われるようになりました。ソフトウェア間で逐次(FIFO)処理されるデータのためのメモリ領域がこちらの使われ方の主戦場といったところでしょうか。

ソフトウェア間でただ一括転送されるデータならバッファという言葉は誤用ということになるのですが、よく誤用されます。

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速...続きを読む

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

QC言語で文字列をかえす正しい書き方が知りたいです?

C言語で次の警告が表示されます。
文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか?


jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。


char *test(char *a, int b)
{
char str[BUFSIZ];
return str; <------

}

Aベストアンサー

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び出し元でちゃんとfreeしましょう。

B-2.呼び出し元でメモリを確保するケース
(注意:同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{

...

return str;
}
これは#1の方の回答と同じです。

B-3.B-1/B-2の複合
(注意:NULL以外の同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{
if(str == NULL)
{
str = malloc(BUFSIZ);
if(str == NULL) return NULL; //エラー
}

...

return str;
}

こんなところですかね。

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び...続きを読む

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

Q関数の配列はできないでしょうか。

ひとつの関数で、出力を配列のように複数させたいのですが、できないでしょうか。

Aベストアンサー

戻り値では1つの値しか返せないので、引数に配列のポインタを渡し、関数内で値をセットするという方法を取ります。

int main(void)
{
  int i, array[10];
  func(array);      /* 配列のアドレスを渡す */
  for (i = 0; i < 10; i++)
    printf("%d:%d\n", i, array[ i ]);
  return 0;
}

void func(int p[ ])    /* pは配列のアドレスを受け取るポインタ */
{
  int i;
  for (i = 0; i < 10; i++)
    p[ i ] = i * i;   /* 適当に値をセット */
}

必要な宣言等は、適宜行って下さい。
配列を受け取るポインタの宣言には人それぞれ好みがあるのですが、私は「単なる変数のアドレスを受け取るのではない」ということを主張している、この方法を取っています。

ちなみに「構造体なら返せる」と言って、配列メンバを持った構造体を返してる人を見たことがありますが、できたとしてもこんな方法はやめましょう。

戻り値では1つの値しか返せないので、引数に配列のポインタを渡し、関数内で値をセットするという方法を取ります。

int main(void)
{
  int i, array[10];
  func(array);      /* 配列のアドレスを渡す */
  for (i = 0; i < 10; i++)
    printf("%d:%d\n", i, array[ i ]);
  return 0;
}

void func(int p[ ])    /* pは配列のアドレスを受け取るポインタ */
{
  int i;
  for (i = 0; i < 10; i++)
    p[ i ] = i * i;   /* 適当に値をセット */
}...続きを読む


人気Q&Aランキング

おすすめ情報