文字列を分割して変数に格納したいのですがうまくいきません。
---以下ソース---
#include<stdio.h>
#include<string.h>
void main(void){
char tai[]="name1=value1&name2=value2&name3=value3&name4=value4";
char *tp;
int a;
int b;
int i;
int co=0;
a=strlen(tai);
for(i=0;i<a;i++){
if(tai[i] == '='){
co++;
}
}
b=co;
char *nameset[b];
char *valueset[b];
*nameset[0]=*strtok( tai,"&=" );
i=1;
co=0;
while ( tp != NULL ) {
if(0==i%2){ co=i/2; *nameset[co] = *strtok( NULL,"&=" ); }
else{ co=i/2; *valueset[co] = *strtok( NULL,"&=" );}
i++;
}
for(i=0;i<b;i++){
printf("%s : %s\n",nameset[i],valueset[i] )
}
}
---ソースここまで---
どうしたらちゃんと変数に格納されますか?
No.6ベストアンサー
- 回答日時:
ちゃんと動くかどうかは、わかりません。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "name1=value1&name2=value2&name3=value3&name4=value4";
char **name, **value, *tp, *dlm = "=&";
int n, i;
for (n = i = 0; str[i]; i++) {
if (str[i] == '=') {
n++;
}
}
name = (char **) malloc(sizeof(char *) * n);
value = (char **) malloc(sizeof(char *) * n);
if (!name || !value) {
exit(0);
}
tp = strtok(str, dlm);
for (i = 0; tp && i < n; i++) {
if (tp) {
name[i] = tp;
tp = strtok(NULL, dlm);
if (tp) {
value[i] = tp;
tp = strtok(NULL, dlm);
}
}
}
for (i = 0; i < n; i++) {
printf("name =%s\n", name[i]);
printf("value=%s\n", value[i]);
}
free(name), free(value);
return 0;
}
この回答への補足
あの後自分なりに皆さんの指摘を参考にソースを再構築してみました
whoilがなくなったので固定数になりましたが
6さんの教えていただいたソースも参考にしますね
ありがとうございました。
#include<stdio.h>
#include<string.h>
void main(void){
char tai[]="name1=value1&name2=value2&name3=value3&name4=value4";
char *nameset[4];
char *valueset[4];
int i;
nameset[0]=strtok( tai,"&=" );
for(i=1;i<8;i++){
if(i%2==0){
nameset[i/2]=strtok( NULL,"&=" );
}
else{
valueset[i/2]=strtok( NULL,"&=" );
}
}
for(i=0;i<4;i++){
printf("%s %s\n",nameset[i],valueset[i]);
}
}
No.7
- 回答日時:
他の回答者への突っ込み+補足のみ.
「名前=値」のリストが & で連結されているので, 最初の forループ内では '=' とではなく '&' と比較するのが筋だと思います>#6. いや, 結局同じなんだけどさ.
あと,
char *nameset[b];
char *valueset[b];
などは C99 (以降) なら OK です>#2. C++ では 11 でも NG ですが, C++ なら std::vector でもつかっとけということで.
この回答への補足
<<「名前=値」のリストが & で連結されているので, 最初の forループ内では '=' とではなく '&' と比較するのが筋だと思います>#6. いや, 結局同じなんだけどさ.
私自身もどちらも同じだと思うのですが=で判定せよ
っと説明を受けたので=で判定するようにしました
<<あと,
char *nameset[b];
char *valueset[b];
ここら辺を修正する事にします
No.5
- 回答日時:
#3です。
●2 *nameset[0]=*strtok( tai,"&=" );
Q。つまり指定先が間違っているのですね
A。代入先も間違っているし代入元も間違っています。多分。
●3 tpの初期化は必要はないのです。tpにstrtokで分割した文字列が入っていれば問題はないと思います
どこでtpに文字列を入れる文がありますか ? 見当たりませんが。
また、初期化しなくてよい理由はありません。私にはtpに何が入っているかわからないで
while(tp !=NULL)
を実行する意味が理解できません。たまたまtpがNULLならwhile内は実行されますが、そうでなければ実行されないという博打のようなプログラムですよ。
この回答への補足
ああすみません。
よく見たら非常におかしな事を書いていました
修正をなんどもっしているうちにへんなことになってたみたいです
申し訳ありませんでした。
No.3
- 回答日時:
完成までは大分道が遠そうだと感じました。
いくつか指摘するだけにしておきたいと思います。
(1) 途中で以下の定義が現れます。
char *nameset[b];
char *valueset[b];
私のコンパイラでは翻訳エラーが出ます。質問者のコンパイラではエラーが出ないものとして話を続けます。
(2) 次の行では
*nameset[0]=*strtok( tai,"&=" );
が現れます。
strtokは検索した文字列の検索結果のポインタを返します。でも*をつけるとそこが指している実体になります。格納先のnameset [0]はポインタを格納する領域を配列としてb個分用意したものですが、まだそこには何が書かれているかわかりません。その何が格納されているかわからない内容をアドレスとして代入したら、往生しまっせ。
(3) 後ろの方に
while ( tp != NULL ) {
という文がありますが、tpは初期化もされていないし、だれも更新しないようですね。それでOKですか?
この回答への補足
●1
その部分はいろいろ修正してみる事にします
●2
つまり指定先が間違っているのですね
●3
初期化は必要はないのです
tpにstrtokで分割した文字列が入っていれば問題はないと思います
No.2
- 回答日時:
いろいろツッコミどころが……
>while ( tp != NULL ) {
tpの値は不定値のまま更新されていません。
よって、ほぼ確実に無限ループします。
>*nameset[0]=*strtok( tai,"&=" );
nameset[0]が指すアドレス(不定値)に…strtok()の戻り値のアドレスに格納されている1文字をコピー…って事になるんですかね。
どこに書き込むかは不明ですので最近のOSならアクセス違反などの例外になるかと思われます。
>char *nameset[b];
>char *valueset[b];
C99で可能…なんでしたっけ?
VC++2010EEでは「error C2057: 定数式が必要です。」となります。
正しく動作する…と思われる修正を行ったとして…
nameset[]とvalueset[]に入るアドレスはstrtok()によって書き換えられたtai[]になります。
よって…tai[]の寿命に影響される点にはご注意を。
この回答への補足
<<tpの値は不定値のまま更新されていません。
よって、ほぼ確実に無限ループします。
事前に部分的につくりはしたのですがそのときは無限ループはしなかったようです。
<<nameset[0]が指すアドレス(不定値)に…strtok()の戻り値のアドレスに格納されている1文字をコピー…って事になるんですかね。
どこに書き込むかは不明ですので最近のOSならアクセス違反などの例外になるかと思われます。
一文字コピーになるのですか¥0で区切られた文字が入るのかと思いました。
>char *nameset[b];
>char *valueset[b];
無理なのですね
すみません他の方法を考えてみますね
<<正しく動作する…と思われる修正を行ったとして…
nameset[]とvalueset[]に入るアドレスはstrtok()によって書き換えられたtai[]になります。
よって…tai[]の寿命に影響される点にはご注意を。
注意しますごしてきありがとうございました
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語にて構造体のメンバがNULL...
-
char*を初期化したいのですが
-
コマンドライン引数 *argv[]は...
-
C言語のintとcharの違いってな...
-
char 文字列型 の表現範囲が-12...
-
CStringからchar*への型変換に...
-
小数点入りの文字列をfloat型に...
-
エクセルのMID関数は、C言語では?
-
ポインタを使用 [数字列を数値...
-
C言語:小文字を大文字に変換す...
-
文字列のswap
-
WritePrivateProfileString
-
csvファイルをfscanfで読み込む...
-
WM_CHAR or WM_KEYDOWN の「wPa...
-
char AA[]{"全角文字"};から"全...
-
fstream型オブジェクトを関数の...
-
文字列str内の全ての数字を...
-
const char* s1とただのchar s1...
-
C言語で文字列をかえす正しい書...
-
動的メモリの初期化方法について。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
strcat関数を自作したいです
-
fstream型オブジェクトを関数の...
-
new charとnew char[N]の違いは?
-
DWORDとcharの変換
-
文字列の途中から途中までを抽出
-
char 文字列型 の表現範囲が-12...
-
const char* s1とただのchar s1...
-
wsprintf( ポインタ , "%d" , "...
-
c言語でポインタ変数を用いた配...
-
char型にint型の数値を代入する。
-
C言語で文字列をかえす正しい書...
-
C++17で、unsigned char * 配列...
-
共用体について
-
エクセルのMID関数は、C言語では?
おすすめ情報