電子書籍の厳選無料作品が豊富!

文字列を分解して特定の項目を別の変数に入れたいのですが、条件式を満たさないので別の変数に入れれません

下にソースを書くのですが age の項目だけ別の変数に入れたいのです
どのようにすれば入れれますか?

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

char *nameset[12],*valueset[12];
char *nameset3[12],*valueset3[12];

void main(void){

int c=0;
int i=0,cn=0,dn=0;
char *tm=NULL;
char *han;
char *a="name=miku&age=15&like=momo";
int b=strlen(a);

nameset[0]=a;
while((a[++i]!=NULL)&&(i<b)){

/* 項目の分解 */
if(a[i]=='='){
a[i]=NULL;

if(c!=1){
valueset[cn]=a+i+1;
cn++;
}

else{
valueset3[dn]=a+i+1;
dn++;
c=0;
}

}

/* データ項目で分解 */
else if(a[i]=='&'){
a[i]=NULL;
han=a+i+1;

if(strcmp(han,"age")==0){
nameset3[dn]=han;
c=1;
}

else{
nameset[cn]=han;
}

}
}

printf("%s\n", nameset[0]);
printf("%s\n", valueset[0]);
printf("%s\n", nameset[1]);
printf("%s\n", valueset[1]);
printf("%s\n", nameset[2]);
printf("%s\n\n", valueset[2]);

printf("%s\n", nameset3[0]);
printf("%s\n", valueset3[0]);
}

A 回答 (3件)

>char *a="name=miku&age=15&like=momo";



aは「書き換え不可能なメモリ領域を指している場合がある」ので、aが指すメモリを

>a[i]=NULL;

のように書き換えても、正しく書き変わる保証はありません。

文字列が「リードオンリーのメモリ」に置かれた場合には「実行時例外:メモリ????????が書き込み可になる事はありませんでした。実行プロセス??????.EXE、プロセスアドレス????????番地」という例外が出てプログラムが強制終了されます。

>if(strcmp(han,"age")==0){

この段階では、hanが指すポインタの文字列は「age=15&like=momo」になっていて、名前と値に分解されていません。

なので、このif文は成り立ちません。

とりあえず

if(strcmp(han,"age")==0){



if(strncmp(han,"age=",4)==0){

にすれば、希望通りになります。

以下、上記の添削を踏まえて、大幅に書き換えました。

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

char a[256]; //aは動的メモリ領域に置く
char *nameset[12],*valueset[12];
char *nameset3[12],*valueset3[12];

void main(void){

int token=0,token3=0;
char *p=a,c;

strcpy(a,"name=miku&age=15&like=momo"); //文字列を動的メモリ領域にコピー

nameset[token]=p;
while((c = *++p) != '\0') {
if((c == '=') || (c == '&')) {
*p++ = '\0'; //区切り文字をヌル文字に変える
if(c == '=') {
valueset[token++]=p; //valueを記録したらトークンを1つ進める
if(strcmp(nameset[token-1],"age")==0){ //分解後にnameがageだったと判ったら
nameset3[token3] = nameset[--token]; //namesetとvaluesetをnameset3とvalueset3にコピーして
valueset3[token3++] = valueset[token]; //トークンを1つ戻して、トークン3を1つ進める
nameset[token] = NULL; //nameset3にコピーされたnamesetを無効にする
valueset[token] = NULL; //valueset3にコピーされたvaluesetを無効にする
}
} else {
nameset[token] = p;
valueset[token] = NULL;
}
}
}

printf("%s\n", nameset[0]);
printf("%s\n", valueset[0]);
printf("%s\n", nameset[1]);
printf("%s\n", valueset[1]);
printf("%s\n", nameset[2]);
printf("%s\n\n", valueset[2]);

printf("%s\n", nameset3[0]);
printf("%s\n", valueset3[0]);
}

この回答への補足

>>>char *a="name=miku&age=15&like=momo";

aは「書き換え不可能なメモリ領域を指している場合がある」ので、aが指すメモリを

>a[i]=NULL;

のように書き換えても、正しく書き変わる保証はありません。

文字列が「リードオンリーのメモリ」に置かれた場合には「実行時例外:メモリ????????が書き込み可になる事はありませんでした。実行プロセス??????.EXE、プロセスアドレス????????番地」という例外が出てプログラムが強制終了されます。

今まで書き換わるものだと思っていたから私はage=15&like=momoに気づかなかったのですね
強制終了はしませんでしたが

<<if(strncmp(han,"age=",4)==0){

にすれば、希望通りになります。

教えていただきありがとうございました
プログラム製作可能なPCに戻してみたらすぐやってみますね

ソースを張り切って書いていただきありがとうございます。
ソースを書いていただけるのは本当にうれしいです

うれしいのですがこちらは質問のために作ったソースなのでこのプログラムを実行しちゃうと大本のプログラムにエラーが出てきそうです

ですが、書いていただいたソースと似たような書き方をすることがこの先あるかもしれません
そのときは遠慮なく使わせてもらいますね

本当にソースを書いていただきありがとうございました

補足日時:2012/12/03 15:16
    • good
    • 0

因みに、ANo.1の



>if(strncmp(han, "age", 3)==0) {

と言う修正は「良くやるミス」なので駄目です。

これでは

agesage=sage

agent=yes

など、頭3文字が「age」になっている「4文字以上のname項目」も全部引っ掛かります。

つまり「age=15以外も引っ掛かる」ので、期待した動作をしません。

この回答への補足

なるほど確かにそうなりますね

たぶん未来の私が気づいたらNAMEの名前に気をつけるなりするんでしょうね
d法はならなかったわけですが

補足日時:2012/12/03 14:48
    • good
    • 0

検証はしておらすコードだけ見てます。



if(strcmp(han,"age")==0){

の部分でhanが参照できる文字列は"age=15&like=momo"となっているはずです。
ですので当然"age"とは一致しません。
単純にこの問題だけクリアしたいだけなら、

if(strncmp(han, "age", 3)==0) {

のように比較する文字数に制限を掛けられる関数を使いましょう。

しかし難解に記述されてますね。'='や'&'で文字列を分解したいのであれば、strtokを使えばグっと楽になりますよ。

この回答への補足

<<の部分でhanが参照できる文字列は"age=15&like=momo"となっているはずです。

ああそうなんですかだからおかしかったのですね


<<しかし難解に記述されてますね。'='や'&'で文字列を分解したいのであれば、strtokを使えばグっと楽になりますよ。

昔はstrtok使ってたのですがないようにNULLが含まれるとずれちゃうんですよ
そのため使わなくなりました

こんなのあるんだと発見したときは喜んだんですけどね

補足日時:2012/12/03 14:34
    • good
    • 0

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