どるこむ仲間の掲示板! 過去ログ倉庫 | LOG:2001/09: | |
●2001年09月インデックス
●過去ログ検索トップ
■どるこむ仲間の掲示板へ
|
[3458] C言語の疑問 (18 レス) 2001/09/06(Thu) 19:49:08 |
ぜふぃみあ さん |
Web: (none) | |
どうも、ぜふぃみあです。 現在C++でcgiプログラムを作成中なのですが、 自作関数内部でうまくいかないところがあるので 調べてみたところ、面白い現象に出くわしました。 void 自作関数(char *s,char *r,char b,char e,int options) { char buffer[256]; (略) for(i = 0;s[i] != '\0';i++) { if((flag == 1) && (s[i] == e)){ // cout << "break point" << i; // デバッグ用 break; } if(flag == 1) buffer[i-h-1] = s[i]; if((flag == 0) && (s[i] == b)) { flag = 1; h = i; } else if((flag == 0) && (b == '\0')) { flag = 1; h=i+1; buffer[i-h] = s[i]; } cout << "buffer" << buffer; //デバッグ用 } という物です。これは何をする関数かと言いますと、sに文字列を 読み込み、bから始まりeで終わる区間の文字列をrに返す、という 物です。このプログラム、bufferの定義のところで for(int i=0;i<257;i++) buffer[i]=0; で初期化してやらないと、うまくいかないことがあります。 FreeBSD4.2-R上でgccを使っているのですが、この初期化は文字列を扱うときに 必要不可欠な物なのでしょうか? (C初心者なので、激しく怒らないで・・・・下さい) あと、他のプログラムで見たのですが int GetForm( FormTerm*& term ) この定義は、ポインタを参照として見る、という意味なので しょうか? よろしくお願いします。m(__)m 最後に確実に"\0"を足しています? sの最後まで行ってしまった場合にしか、"\0"がbufferに付かないように見えます。そのせいではないかと。
あ・・・・すいません。あの後に
buffer[i] = '\0'; strcpy(r,buffer); がつきます。 私はC言語しかわからないのでC++はイマイチよくわからないのですが、
関数内で宣言されたローカル変数は何が入っているかわからないってことになっていたと思います。 私なんかは文字定数レベルで文字列バッファに格納する場合は必ず memset(buffer,0x00,sizeof(buffer)); とか書いて初期化してから使うことにしています。 たぶん、それじゃないかな? >この初期化は文字列を扱うときに必要不可欠な物なのでしょうか? 絶対必要ではないと思いますが、やっておくに越したことはないと思いますよ。 特に文字列と文字定数の扱いがごっちゃになっているときは。 4. たかぼう 2001/09/06(Thu) 21:37:09
buffer[i-h]='\0'ではないのですか?
一つ気になったのですが、r に返す文字列は b の文字は含まれないのかな?
なんか入らないような気がするですけど。 見間違いならごめんなさい >char buffer[256];
>for(int i=0;i<257;i++) buffer[i]=0; 死にますよ、これでは・・・。 あと、初期化は別に必要ないです。 flag はどこで宣言しているのですが?初期化していますか? えげつない組み方をすれば、こんなもんでどうでしょ。
void 自作関数(char *s,char *r,char b,char e) { char *_b, *_e; if((_b = strchr(s, b)) == NULL) return; if((_e = strrchr(s, e)) == NULL) return; strncpy(r, _b, _e - _b + 1); r[_e - _b + 1] = '\0'; } ロクにチェックしてない(笑) おお、こんなにレスが。ありがとうございます。
>関数内で宣言されたローカル変数は何が入っているかわからないってことになっていたと これですが、その通りです。下の方でcout << bufferとなっていますが、これは あらかじめbufferに何が入っているのかを調べる物です。 これで調べると、むちゃくちゃな値が入っていました。 それを見ると、最終的に初期化の必要はないかと思ったのですが 初期化をしないとうまく動かない場合もあり、とても疑問です。 >buffer[i-h]='\0'ではないのですか? ですが、最終文字にヒットした場合iの値がその添え字なので そこにヌル文字を入れています。hは最初の文字がヒットした場所です。 違いますかね?・・・ >一つ気になったのですが、r に返す文字列は b の文字は含まれないのかな? あっ、これですが含まれず、でokです。bとeはあくまで目印なので そこから始める、というわけでなくその次から、というわけです。 本文おかしいですね・・・すいません。 >死にますよ、これでは・・・。 あぅ・・・その通りですね・・・変えてきます。 アドバイスありがとうございます。 >HIRさん おお、このような組み方が(笑) 参考にさせていただきます。φ(.. )メモ 結果ですが、やはり初期化しないとうまくいかないみたいです。 最後の方で文字化けしている模様・・・cout << bufferで見ると ./test.cgi(π・@ このような感じになっており、うまくiの後に\0が入っていないようです。 >>初期化しないとうまくいかない
bufferに'\0'が本当に入っているかどうかデバッガ(gdbなど)で、 適当なところにブレークポイントを設定して一行づつステップ実行して 確かめるのが一番じゃないかなぁ〜。 >>あと、他のプログラムで見たのですが >>int GetForm( FormTerm*& term ) 私は見たことないです(^^;;; ポインタ値を参照で渡す? わからん(^^; 10. SLIM 2001/09/07(Fri) 01:31:12
こういう話題がでてくると
「あぁ どる仲って 寄席じゃないんだなー」と 関心したり(ぉ 11. sagiyama@AL13C 2001/09/07(Fri) 13:15:54
>どる仲って 寄席じゃないんだなー」と
えっ!違うの?!Σ( ̄□ ̄ )ガビーン! 12. .BlackBox.大佐 2001/09/07(Fri) 13:32:35
>えっ!違うの?!
違います、笑点です 13. たまちゃん 2001/09/07(Fri) 13:42:59
> 違います、笑点です
ご褒美は? 14. src 2001/09/07(Fri) 14:22:28
>>int GetForm( FormTerm*& term )
ポインタ変数自体を参照渡しするって意味です。 ポインタのポインタと、おんなじようなものですが、 こちらを使ったほうがちょっとスッキリしますね。 //------------------------------------------------------------------------------ #include <string> #include <stdio.h> extern std::string g_strX("global string"); void funcRP(char *& rp) { rp = const_cast<char*>(g_strX.c_str()); } void funcPP(char ** pp) { *pp = const_cast<char*>(g_strX.c_str()); } int main(int argc, char* argv[]) { char *p1=0, *p2=0; funcRP(p1); funcPP(&p2); printf("p1 = %s (0x%p)\np2 = %s (0x%p)\n", p1, p1, p2, p2); return 0; } 15. 聖者98狂(KEIN@PSO) 2001/09/07(Fri) 15:01:03
>ご褒美は?
おーい山田君座布団2枚やってくれっ >>ポインタのポインタと、おんなじようなものですが、
>>こちらを使ったほうがちょっとスッキリしますね。 あ〜、なるほどー。今度からそう書こっと(^^;;; 17. 皇帝スーパーブラックバード 2001/09/07(Fri) 16:41:42
COBOL74しか知らないんで参加できない(ゴミ
しかも8割がた忘れてるし(更ゴミ #条件分岐(evaliate?スペルうろ覚え)使って先輩にどやされた記憶が(^^;; >>ポインタのポインタと、おんなじようなものですが、
>>こちらを使ったほうがちょっとスッキリしますね。 あ、なるほど。確かに(^^ゞ evaliate・・・フランス語ですか?(ぉ BASICと最近C言語、むかーーーしアセンブラとマシン語やった位なので 言語はまだまだレベルが低いです(T^T) 頑張らないと |