非常に基礎的な質問で申し訳ないのですが
mainから渡した文字列を関数内で書き換えることができません。
int型の整数やchar型一文字はできるのですが。。。
例えば以下のようなソースでmainのABCをDEFに書き換えたいとき
どのようにすればいいのでしょうか。
(関数の戻り値で変更という方法以外で)
以下のソースでは値は書き換わりませんでした。
void func(char *str2)
{
str2 = "DEF";
}
int main()
{
char str1[20] = "ABC"
printf("%s", str1); //ABC
func(str1);
printf("%s", str1); //DEFになるようにしたい
}
No.3ベストアンサー
- 回答日時:
Cには値渡し(Call by value)しかないので、str2に直接値を代入しても呼び出し元では値が変わらないですね。
例えば、次のようにすると呼び出し元でも値が変わります。
void func(char *str2)
{
str2[0] = 'D';
str2[1] = 'E';
str2[2] = 'F';
}
Cの文字列変数は文字列の先頭文字に対するアドレスが入っているだけなので、funcが呼ばれたとき、str2にはmain()のstr1のアドレスが入っています。元の書き方ではこのstr2に"DEF"という文字列の先頭文字に対するアドレスを代入しているだけなので、main()のstr1の中身は変わりません。余談ですが、このようにアドレスを格納した変数のことをポインタといいます。
ちなみに、同じ事を文字列操作関数を使ってやるとこんなかんじです。
#include <string.h>
void func(char *str2)
{
strcpy(str2, "DEF");
}
この場合、呼び出し元はstr2の最大サイズを知らず、多めに書きこんでしまう可能性があります。そして、確保した容量以上にメモリーを使用するとプログラムを異常終了させたり、プログラマの意図しない誤った動きをさせたりすること (バッファ溢れ攻撃) が可能となります。
よって、この様なプログラムを書いたほうがよりよいでしょう。
#include <stdio.h>
#include <string.h>
void
func(char *str, size_t str_size)
{
strncpy(str, "DEF", str_size - 1);
str[str_size - 1] = '\0';
}
int
main(void)
{
char str1[20] = "ABC";
printf("%s\n", str1);
func(str1, sizeof(str1));
printf("%s\n", str1);
return 0;
}
strncpy(str, "DEF", str_size - 1);はstr_size - 1の長さだけ"DEF"を書き込む関数で、最期の一文字をNULL文字で終了させない場合があるのでstr[str_size - 1] = '\0';しないといけません。この問題を解決するためにstrlcpyという関数を代わりに使うケースもあります。
No.6
- 回答日時:
>例えば以下のようなソースでmainのABCをDEFに書き換えたいとき、どのようにすればいいのでしょうか。
「ABC」を「DEF」の同じ連番記載に換えたいということですよね。
やり方は2通りあると思います。
1つはあなたが承知の文字定数「DEF」に換える場合と、もう一つは元の文字について一定の幅を持たせて任意の「DEF」に換える場合です。
前者の場合は #1 さんの strcpy()関数を使うのが良いと思います。ただし、string.hヘッダーファイルを include しなければなりません。
後者の場合は↓に示す方法で、与えられた文字列str2全部に対して一定の幅を持たせて変換するものです。
まあ、結局は好みの問題でもありますが...。
/* 定数3の理由:A,B,C,D -> 4番目のD-1番目のA */
void func(char *str2){
while(*str2) *str2++ += 3; //str2文字列の最後まで変換
}
すみません、ABCをDEFにというのは一例で
連番にしたいというわけではなかったです。
でも、連番だとそのような考え方もあるのですね。
ありがとうございます。
No.5
- 回答日時:
例えば
void testmain()
{
int i=0;
test(&i);
printf("%d",i);
}
void test(int*p)
{
*p=1;
}
の場合、&iが0x1000とすると、test内では0x1000の内容が1に変更されるため、testmainでもiの値が変わります。
ところが、
void testmain2()
{
char str[10] = "ABC";
test2(str);
printf("%s",str);
}
void test2(char* p)
{
p="DEF";
}
としたとき、strが0x2000、"DEF"の先頭アドレスが0x3000とすると、test2内ではpの値が0x3000に変更されるだけで、0x2000にあるデータは"ABC"のままです。当然、testmain2ではstrの値は0x2000なので、文字列は変更されません。
No.4
- 回答日時:
Cでは「文字列」という型は無くて、「ポインタ/配列が示す場所から0までのchar」を文字列として扱う、というルールで運用しています。
プログラムを作る際は、他の数値型とは分けて、他の数値型の配列やポインタを扱うようなつもりで考える必要があります。
たとえば
void func(int *n2)
{
int n0={1,2,3} ;
n2 = n0 ;
}
これが、実質何もしない、ということはおわかりですね? あなたの書いたfunc関数は上のintをcharの置き換えただけのものです。
No.1
- 回答日時:
ポインタの理解が足りませんね。
str2自体は仮引数なのでfunc関数から抜けると消滅します。
だからstr2をいくらいじっても無駄なのです。
ポインタそのものをいじるのじゃなくて、ポインタが指しているメモリに書き込まないとね。
void func(char *str2)
{
strcpy(str2, "DEF");
}
これでOK
この回答への補足
ありがとうございます。
func関数から抜けると消滅するということは分かるのですが
int型の場合、参照で渡して
*str2 = 10;
のようにすればstr1も置き換わると思います。
char配列型の場合は似たような記述方法はないのでしょうか?
strcpyのような関数を使わなければ無理ですか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
入力された文字列の中の数字を...
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
文字列strの中から文字cを探す...
-
char 文字列型 の表現範囲が-12...
-
fstream型オブジェクトを関数の...
-
C言語の文字リテラル中の16進文...
-
char型について【初心者です】
-
コマンドライン引数 *argv[]は...
-
GlobalAlloc関数について
-
2次元配列の文字"列"の初期化方法
-
C言語のintとcharの違いってな...
-
文字列の連結
-
char型にint型の数値を代入する。
-
csvファイルを構造体に格納した...
-
new charとnew char[N]の違いは?
-
C言語 動的なメモリの確保 実...
-
全体をNULLクリアするより、最...
-
DWORDとcharの変換
-
strcpy関数で文字型変数へのポ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
char型にint型の数値を代入する。
-
const char* s1とただのchar s1...
-
new charとnew char[N]の違いは?
-
動的メモリの初期化方法について。
-
エクセルのMID関数は、C言語では?
-
C言語 strstrの実装
-
SetWindowTextについて。
-
char 文字列型 の表現範囲が-12...
-
文字列の途中から途中までを抽出
-
2次元配列の文字"列"の初期化方法
-
DWORDとcharの変換
-
C++17で、unsigned char * 配列...
-
C言語の文字リテラル中の16進文...
-
strcat関数を自作したいです
おすすめ情報