マンガでよめる痔のこと・薬のこと

プログラム初心者です。現在、下のようなプログラムを作成して文字列をprintf出力しております。現状、文字列データの一部(何バイト目からここまでとか)を他の場所に抽出や取得をしたいのですが、それが出来なく大変困っています。
文字列の取得例)
aaaa.aa|xxx.xx|yyyy.yy|iiii
今、取得したい部分はx,y,iの部分で、文字数は100文字出力させております。

inti,loop;
charsendValue[100];
charreadValue[100];
intret;
intloopCnt;

loopCnt = 0;
ret = 0;
strcpy(sendValue,sendMsg);


printf("send\n");

for(i=0;i<len;i++){
write(fd,&sendValue[i],1);
usleep(50000);
}

while(1){
      ret = read(fd,readValue,100);
printf("read-ret:%x\n",ret);
if(ret!=0xffffffff){
printf("readValue(%s):",ret);
for(i=0; i<ret; i++){
printf("%02X ",readValue[i]);
}
printf("\n");

return 0;


こんな感じです。ご教示お願いいたします。

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

A 回答 (1件)

その「抽出したい」というのがどんな条件で、どんな風にやりたいのかがはっきりしないのですが。


単純には

while(i=0;抽出元が区切り文字?になるまで,または抽出する文字数まで; ++ i){
抽出結果[i]=抽出元[i+抽出開始の添字] ;
}
抽出結果[抽出した最後+1]='\0' ;

となるでしょう。場合によってはstrtokとかsscanfとかも有用でしょう。


あと、細かいようですが。

> if(ret!=0xffffffff)

このreadがシステムコールのものなら、今あなたが使っている環境では正しく動作するかもしれませんが、常に正しいとは限りません。
標準のCなら、マニュアルには「戻り値は読み込んだ文字数/失敗したら負の値」って書いてないですか?
環境によっては(例えば、intが64bitのCだったら) 0xfffffffff は「正」なので「失敗とは限らない」し、失敗で返ってくるのも必ず-1とは限らないです。

> printf("readValue(%s):",ret);
retはint型です。%sはcharへのポインタを要求します。
Cではprintfの中の型の不一致はエラーにはなりません。しかし、結果として致命的なエラーになるケースはあります。
この場合だと、retに入っている「文字数」を、「文字列が始まるアドレス」と解釈されてしまい、不正はエリアにアクセスしてしまうかもしれません。
    • good
    • 0
この回答へのお礼

わざわざご丁寧に質問以外の点までご回答いただきましてありがとうございます。大変助かりました。
参考にさせていただきます。ありがとうございました。

お礼日時:2011/10/01 22:19

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

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

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_...続きを読む

Q文字列の途中から途中までを抽出

文字列の一部を抽出したいときのプログラムです。
絶対条件は
・文字列はchar*型
・ある文字で区切られた区間を抽出
です。

以下のコードだとstrncpyの部分でsegmantation faultになってしまいます。
--------------------------
char array[10] = "abcd/efgh";
char* str0
char* str1;
char* str2;
int = len;

str0 = array;
len = strstr(str0, "/") - str0;

strncpy(str1, str0, len);
str2 = array + len + 1;
--------------------------

各変数が
str1 = abcd
str2 = fghi
となるようにしたいです。

char str1[10];などにすればいいのですが、それ以外の方法でお願いします。

Aベストアンサー

>str2 = strtok(null, "/");

str2 = strtok((char*)0, "/");
かもしれません。

>後からarray[]の内容を変更した場合のstr1およびstr2は機体と別の動作しますけど。

後からarray[]の内容を変更した場合のstr1およびstr2は期待と別の動作しますけど。
です。
str1 = strtok(array, "/");
str2 = strtok((char*)0, "/");
strcpy(array, "012345678");
とかやった場合とか。

Q入力された文字列から整数だけを取り出す方法

入力された文字列から整数だけを取り出すにはどうしたらよいのでしょうか?
例えば、

(1,1,4,4,2,3,2,3)

と入力された時、'(' や ',' は無視して、

1 1 4 4 2 3 2 3

のみを取り出したいのですが。。
自分なりにiostreamの関数について調べてみたのですが、良い方法が思いつきません。
どなたかお力添えをお願いいたします。

Aベストアンサー

LippmanのC++プライマー(第4版)のp.340~p.342に、
8.5 stringストリーム
という節があって、p.342に、

「istringstream を使って format_message(数値と文字列の並びが格納された ostringstream オブジェクト)を読めば数値を取り出すことができる。
文字列表現を数値に自動変換してくれるのである。

istringstream input_istring(format_message.str());
string dump;
input_istring >> dump >> val1 >> dump >> val2;   」

て書いてありました。
input_istring の内容構成について知っていなければならない条件付きですけど。
ちなみにヘッダは sstream です。

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言語文字列置換

初心者です。みなさまどうか教えてください。(>_<)

文字列置換関数をつくれ
ただし文字列操作系関数はつかうな(str---)。
void replace(char*str, char*before,char*after);

Aベストアンサー

以下のようにしてください。
---------------------------------------------
#include <stdio.h>
#include <string.h>
//自前の文字列操作関数
//strのlengthを返す(自前のstrlen)
int mystrlen(char *str){
int i = 0;
while(*str){
i++;
str++;
}
return i;
}
//メモリの比較を行う(自前のmemcmp)
int mymemcmp(void *str1,void *str2,int len){
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
int i = len;
if (len == 0) return 0;
while(*s1 == *s2){
i--;
if (i == 0) return 0;
s1++;
s2++;
}
return (*s1 - *s2);
}
//メモリのコピー(str1<--str2)(自前のmemmove)
void mymemmove(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
if (s1 < s2){
while(len > 0){
len--;
//前からコピー
*s1++ = *s2++;
}
}else{
while(len > 0){
len--;
//後ろからコピー
*(s1+len) = *(s2+len);
}
}
return;
}
//メモリのコピー(str1<--str2)(自前のmemcpy)
void mymemcpy(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
while(len > 0){
len--;
*s1++ = *s2++;
}
return;
}
//課題の関数
//myxxxxのmyをとり実際に存在するxxxxを呼び出しても同じ結果が得られる筈
//例 mystrlen--->strlen
//例 mymemcmp--->memcmp
//例 mymemcpy--->memcpy
//例 mymemmome--->memmove
void replace(char *str,char *before,char *after)
{
int slen = mystrlen(str);
int blen = mystrlen(before);
int alen = mystrlen(after);
int len;
char *s = str;
char *from;
char *to;
/*
if (blen < alen){
printf("afterの長さ>beforeの長さの為処理を中止します\n");
return;
}*/
while(*s){
//str中にbeforeがあるかチェックする
if (mymemcmp(s,before,blen) == 0){
//存在する場合
//beforeの後の文字列の移動
from = s + blen;
to = s + alen;
len = mystrlen(from);
mymemmove(to,from,len);
//終端に\0を設定
*(to+len) = '\0';
//文字列の置換
mymemcpy(s,after,alen); //mymemmoveを使用しても問題ない
//次は置換された文字列の次から処理する
s = to;
continue;
}
s++;
}
}
//replace呼び出し前後のstr,bofore,afterの内容を表示
void test(char *str, char *before,char *after)
{
printf("実行前\n");
printf("<%s> <%s> <%s>\n",str,before,after);
replace(str,before,after);
printf("実行後\n");
printf("<%s> <%s> <%s>\n",str,before,after);
}
int main(void)
{
char str[256];
strcpy(str,"abcXXefgXXxyzXX");
test(str,"XX","YYY");
strcpy(str,"abcXYZefgXYZxyzXYZ");
test(str,"XYZ","AB");
strcpy(str,"abcXXXXXX");
test(str,"XX","ABCD");
return 0;
}
----------------------------------------------
以下、実行結果です。
実行前
<abcXXefgXXxyzXX> <XX> <YYY>
実行後
<abcYYYefgYYYxyzYYY> <XX> <YYY>
実行前
<abcXYZefgXYZxyzXYZ> <XYZ> <AB>
実行後
<abcABefgABxyzAB> <XYZ> <AB>
実行前
<abcXXXXXX> <XX> <ABCD>
実行後
<abcABCDABCDABCD> <XX> <ABCD>

以下のようにしてください。
---------------------------------------------
#include <stdio.h>
#include <string.h>
//自前の文字列操作関数
//strのlengthを返す(自前のstrlen)
int mystrlen(char *str){
int i = 0;
while(*str){
i++;
str++;
}
return i;
}
//メモリの比較を行う(自前のmemcmp)
int mymemcmp(void *str1,void *str2,int len){
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
int i = len;
if (len == 0) return 0;
while(*s1 == *s2)...続きを読む


人気Q&Aランキング

おすすめ情報