課題で
strstr()と同じ働きをするmy_strstr()を実装しなさいという課題がでています。
strstr()は
char *strstr(const char *s1, const char *s2)
という形で、
文字列s2が文字列s1の中に含まれていれば、文字列1の文字列2が含まれている先頭のアドレス(ポインタ)を返す関数です。(すいません、説明が下手で)
例えば、 strstr(Japanese, pan)は Japanese にpan が 含まれるのでpan 以降の文字列を返します→panese
***********************
質問ですが、
strstrの実装は完成して、正常に動くのですが
警告がでてきます。
str1= Japanese str2 = pan
とすると、
私のプログラムでは、次のようなプロセスで動きます。
一文字ずつ調べる
↓
str1のJと str2の pを比較
J != p → str1++; //str1の次の文字へ
str1のaと str2の pを比較
a != p, str1++; //str1の次の文字へ
str1のpと str2の pを比較
p == p, rec = str1 // str1のアドレスを記録
str1++; str2++; //次の文字へ
str1のaと str2の aを比較
a == a, str1++; str2++; //次の文字へ
str1のnと str2の nを比較
n == n, str1++; str2++; //次の文字へ
str1のeと str2 nullを比較
*str2 = null //search 終了。
return rec;
とこんな感じです。
このプロセスの3行目の
rec = str1;
つまり、関数の戻り値のために記録したstr1のところで、
「問題のあるポインタ変換」
という警告がでます。
これは s1がconstだからでしょうか?
どのようにしたらこの警告が消えるでしょうか?
どなたかよろしければアドバイスをいただけませんか。
お願いします。
No.3ベストアンサー
- 回答日時:
★キャストをすれば良い。
・下のようになります。
サンプル1:
char *my_strstr( const char *str1, const char *str2 )
{
char *rec;
/* 処理 */
rec = (char*)str1;
/* 処理 */
return( rec );
}
サンプル2:
char *my_strstr( const char *str1, const char *str2 )
{
const char *rec;
/* 処理 */
rec = str1;
/* 処理 */
return( (char*)rec );
}
解説:
・代入時にキャストするサンプル1と return 文でキャストするサンプル2のどちらかの方法を
取って下さい。私はサンプル2の方法をよく利用します。
・以上。参考に。
No.4
- 回答日時:
> これは s1がconstだからでしょうか?
> どのようにしたらこの警告が消えるでしょうか?
そうです。既に回答が出ているように、キャストをすれば警告は消えます。あるいは、処理系によってはコンパイルオプションや#pragma指令を工夫することでも警告を消せるでしょう。
ところで提案なのですが、この警告は消さない方がよいのではないでしょうか?strstr関数は、第一引数にchar*型をわたしたときに返却値をキャスト無しでchar*に代入できるように、このような仕様になっています。しかし、素性も分からないconst char*をchar*に変換するのは、必ずしも望ましいことではありません。警告が出てもエラーになることは規格上ありませんし(警告をエラーとするようなコンパイルオプションを使ったり、非標準処理系の場合は別)、動作も保証されますから、この警告は備忘録として放置しておくのも有効な選択ではないかと思います。
ちなみに、C++ではこのような問題を解消するため、
char* strstr(char*, const char*);
と
const char* strstr(const char*, const char*);
が多重定義されます。
回答ありがとうございます。
自分の知識不足で、
「このconst char*が素性のわからないもの」
なのかすらわからないです。
ここのconst char*をchar* に変換することは危険なことなのですか?
そこら辺の疑問は先生に相談することにします。
とにかく、回答ありがとうございました。
専門家さんの回答は、勉強になります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- Visual Basic(VBA) VBAで時間(00:00形式)を積算(足し算)したい 1 2022/11/15 17:04
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
- Visual Basic(VBA) countifsについての質問 3 2023/03/08 13:45
- その他(自然科学) 信頼度がR1、R2の機器を並列に接続した場合、システム全体の信頼度はどれか。答え1-(R1)(1- 2 2023/01/15 21:45
- 電車・路線・地下鉄 初台→新宿3→代官山(7.6km)IC528円 笹塚→新宿3→中目黒(10.2Km)IC433円なぜ 5 2022/11/24 09:26
- FTTH・光回線 ビッグローブ光とルーターの相性 2 2023/03/18 19:44
- 物理学 この問題における抵抗r1とxってどのように考えれば良いのでしょうか?トルクはT=P2/ωsなのでP2 1 2022/06/19 18:46
- 数学 領域の問題について質問です。 実数s, tは,s^2+t^2≦1, s≧0, t≧0 を同時に満たし 3 2023/05/18 20:59
- Visual Basic(VBA) ワークシートチェンジで曜日を表示する方法 1 2023/03/04 21:51
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
char*を初期化したいのですが
-
ポインタを使って回文かどうか...
-
C言語のintとcharの違いってな...
-
小数点入りの文字列をfloat型に...
-
CStringからchar*への型変換に...
-
ポインタ配列
-
C言語にて構造体のメンバがNULL...
-
C言語:小文字を大文字に変換す...
-
strcat関数を自作したいです
-
char 文字列型 の表現範囲が-12...
-
C# ポインタ アクセス違反
-
new charとnew char[N]の違いは?
-
strcat関数
-
C++Builder 2009 テキスト...
-
36進数
-
[C] 構造体メンバーのカンマ区...
-
コマンドライン引数 *argv[]は...
-
DWORDとcharの変換
-
2次元配列の文字"列"の初期化方法
-
メモリを0クリアする方法について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のintとcharの違いってな...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
CStringからchar*への型変換に...
-
strcat関数を自作したいです
-
new charとnew char[N]の違いは?
-
csvファイルをfscanfで読み込む...
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
C言語で文字列をかえす正しい書...
-
文字列str内の全ての数字を...
-
char 文字列型 の表現範囲が-12...
-
DWORDとcharの変換
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
const char* s1とただのchar s1...
-
文字列内の数字削除
-
c言語でポインタ変数を用いた配...
-
szとlpszの違い
おすすめ情報