質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

3625閲覧

c言語、文字列の交換における3つの方法

mashiba3

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/03/15 21:36

前提・実現したいこと

文字列の交換

文字列の交換には、
1、文字列を指すポインタの交換による実現方法
2、配列を交換する関数を使った(1文字ずつ交換)実現方法
3、配列を一端他の配列に保存して交換する実現方法
があり、それぞれ以下の特徴があることがわかりました。

1、コードが簡単
2、少ないメモリで実現できる
3、配列の容量が大きいときメモリを大量に占有してしまう

今回、3の方法での実現を目的にプログラムしてみました。

発生している問題・エラーメッセージ

配列を一端他の配列に保存して交換しようとする際、main関数における文字列の宣言をポインタによる文字列で宣言するとエラーとなる。
配列による文字列で宣言するとうまくいく。

該当のソースコード

/char s1,s2をポインタによる文字列で宣言するとエラーになるのはなぜなのか/
/char s1,s2を配列による文字列で宣言するとうまくいく/

#include <stdio.h>

void swap_str(char s1[], char s2[])  /*もしくは、char *s1,char s2を仮引数にする/
{
char temp[128];
int i;

for (i = 0; (temp[i] = s1[i]) != '\0'; i++) {  /*もしくは、temp[i]=*(s1+i)!='\0' */ ; } for (i = 0; (s1[i] = s2[i]) != '\0'; i++) { ; } for (i = 0; (s2[i] = temp[i]) != '\0'; i++) { ; }

}

int main(void)
{
char *s1 = "ABC";
char *s2 = "DEF";

printf("文字列s1は\"%s\"です。\n", s1); printf("文字列s2は\"%s\"です。\n", s2); swap_str(s1, s2); puts("文字列s1とs2を交換しました。"); printf("文字列s1は\"%s\"です。\n", s1); printf("文字列s2は\"%s\"です。\n", s2); return 0;

}

試したこと

main関数で、char s1[128]="ABC"; char s2[128]="DEF"と宣言するとうまくいった。

補足情報(FW/ツールのバージョンなど)

コンパイラは、visual studio 2017です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

char *s1 = "ABC";

char s1[] = "ABC";
で、何が違うのかの理解が必要です。
前者は、"ABC"は文字列リテラルと呼ばれるもので、メモリ上のどこかに配置された"ABC"のアドレスをs1に入れています。
後者は、文字の配列を"ABC"+ヌル文字分確保しています。
文字列リテラルの場合、メモリ上のどこかというのはリードオンリーな領域なので、書き換えようとすると質問のようなエラーになります。
以下のサイトで解説されていましたので、ご覧になってみてください。
配列とポインターと、そして文字列リテラルとかの話

投稿2018/03/16 00:16

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mashiba3

2018/03/16 09:04

丁寧な回答ありがとうございました。
guest

0

char *s1 = "ABC";
まず、このポインタの指し先ってのは定数の文字列となり、内容の変更はできません(というタテマエです)
んで、この差し先は、メモリ容量的に4文字分しか確保されません
なので、それ以上のデータをコピーすると最悪暴走します


ポインタを使用する場合は、指し先の実体がどうなっているか、どれだけ確保されているか、を常に注意する必要がありますねー

投稿2018/03/15 22:05

編集2018/03/15 22:08
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mashiba3

2018/03/16 09:05

回答ありがとうございました。 ”ポインタの指し先ってのは定数の文字列となり、内容の変更はできません”の一文で納得することができました。
y_waiwai

2018/03/16 09:21

まあ、ホンマは定数なんだけど、PCなんかの場合は全部SDRAM上に配置されるので、ワーニング無視して書き換えに行くと書き換えられちゃいますw 同様に、指し先の容量のチェックもないので、簡単に書き込みオーバーして簡単に暴走するっていう、最近のモダンな言語にありえないところが、Cの自由なところでもあり難しいところでもありますねーw
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問