![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
文字列を分解して特定の項目を別の変数に入れたいのですが、条件式を満たさないので別の変数に入れれません
下にソースを書くのですが 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]);
}
No.2ベストアンサー
- 回答日時:
>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に戻してみたらすぐやってみますね
ソースを張り切って書いていただきありがとうございます。
ソースを書いていただけるのは本当にうれしいです
うれしいのですがこちらは質問のために作ったソースなのでこのプログラムを実行しちゃうと大本のプログラムにエラーが出てきそうです
ですが、書いていただいたソースと似たような書き方をすることがこの先あるかもしれません
そのときは遠慮なく使わせてもらいますね
本当にソースを書いていただきありがとうございました
No.3
- 回答日時:
因みに、ANo.1の
>if(strncmp(han, "age", 3)==0) {
と言う修正は「良くやるミス」なので駄目です。
これでは
agesage=sage
agent=yes
など、頭3文字が「age」になっている「4文字以上のname項目」も全部引っ掛かります。
つまり「age=15以外も引っ掛かる」ので、期待した動作をしません。
この回答への補足
なるほど確かにそうなりますね
たぶん未来の私が気づいたらNAMEの名前に気をつけるなりするんでしょうね
d法はならなかったわけですが
No.1
- 回答日時:
検証はしておらすコードだけ見てます。
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が含まれるとずれちゃうんですよ
そのため使わなくなりました
こんなのあるんだと発見したときは喜んだんですけどね
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
【C言語】全角文字の配列を、全...
-
空白を含んだ文字列がうまく格...
-
プログラミング 難問
-
タイムカードのシステムを作り...
-
いつもお世話になっております...
-
AtCoderABC135の問題Cについて
-
信頼区間の1.96や1.65ってどこ...
-
マイナスからプラスへ転じた時...
-
C言語での引数の省略方法
-
「Aに対するBの割合」と「Aに対...
-
「指定されたキャストは有効で...
-
エクセルで可視セルにのみ値貼...
-
c言語でAからZまでを表示する...
-
Eclipseコンソール表示を、リセ...
-
C++にてtemplateで受け取った任...
-
プログラミング初心者です。 Py...
-
ファイル名である文字列からbas...
-
EXCELの分散分析表のP-値が....
-
Aの値からBの値を除するとは??
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
#defineが使用するメモリ領域に...
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
【C言語】全角文字の配列を、全...
-
reallocでエラー
-
C言語のプログラムで、途中で止...
-
構造体メンバの初期化
-
char型2つを結合し、short型に...
-
C言語でのCSVファイルの読み出...
-
エラーについて質問です。
-
Cでファイルの行数をカウントす...
-
矢印キーを押下してコンソール...
-
終了条件Ctrl+zについて,結果表...
-
受信データから必要な部分のみ...
-
リストの作成と出力(C言語)
-
大量のファイルを読み込み、そ...
-
Ç言語でファイルサイズを変更す...
-
C++で指定文字列のカウント方法...
おすすめ情報