みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

文字列を関数に渡すぷろぐらむなのですがおかしいです。

<ソース>
#include<stdio.h>
#include<stdlib.h>

void str(char a[]);

int main()
{
char st[10]="abcde";

str(st);
str("ABCabc123");

return 0;
}
void str(char a[])
{
int i;

printf("%s\n",a);
i=0;
while(a[i]){
a[i]=toupper(a[i]);
putchar(a[i]);
i++;
}
putchar('\n');
}
分からないところがあるので質問します。
toupperは、大文字にするんですよね。
putcharは、基本的にchar型でしたっけ?
putsとgetsは、int型でしたっけ?
後、プログラムが暴走してます。
どこがおかしいんでしょう?

投稿日時 - 2009-05-16 11:33:17

QNo.4962980

困ってます

質問者が選んだベストアンサー

>toupperは、大文字にするんですよね。

そのとおりです。

>putcharは、基本的にchar型でしたっけ?

意味的にはcharなのですが、引数としてスタックに積む際、最小単位がintになってしまうので、int型で渡す定義になってます。

>putsとgetsは、int型でしたっけ?

最後の「s」は「string」の「s」なので、char*を渡します。

> char st[10]="abcde";
> ・・・
> str(st);

まずここですが、char型の値10個分の配列が作られ、先頭の6つが"abcde"と'\9'で埋まってます。
これは書き換えが出来ますから、配列のサイズをはみ出なければ問題ありません。
しかし、次は大問題です。

> str("ABCabc123");
> ・・・

"ABCabc123"は「リテラル文字列」であり、通常は定数として扱われます。
定数は書き換えてはいけません。にもかかわらず、書き換えてしまってます。

>void str(char a[])
>{
> ・・・
>   a[i]=toupper(a[i]);

処理系によっては、メモリアクセスエラーとなって、異常終了するでしょう。

投稿日時 - 2009-05-16 12:13:03

お礼

確かにその通りだと思います。
ありがとうございます。

投稿日時 - 2009-05-16 12:28:10

ANo.3

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

zwi

念のためにお聞きしますが、デバッガでステップ実行されましたか?
ポインタ(文字列)を理解するためにステップ実行したほうが良いとコメントしたはずですが。
デバッガがちゃんと使えていたら、どこで問題が出たか把握できるはずです。

>後、プログラムが暴走してます。
暴走じゃなくて異常終了では?
定数"ABCabc123"をtoupperしているのが原因です。
定数を書き換えることはOSが保護しているので出来ません。
書き換えられたら定数の意味がないので、プログラムがおかしいのであってOSとコンパイラは正しいです。

投稿日時 - 2009-05-16 12:01:02

ANo.1

質問の内容がよくわかりませんが、
関数の使い方がわからないけど、調べるつもりは無いので、教えてくださいって事かな?

関数の使い方については、リファレンスを参照して下さい。
その上で、疑問点を質問するとよいです。

> 後、プログラムが暴走してます。
> どこがおかしいんでしょう?
ですが、これはわかりにくいかもしれないので、少しヒントを
> str("ABCabc123");
の部分で、文字列定数を、str()関数に渡していますが、
文字列定数は、読み取り専用領域に配備される事があります。
ので、
> a[i]=toupper(a[i]);
の部分で、読み取り専用領域に書き込みしようとして、
セグメンテーションエラーか、アプリケーションエラーに
なっているのではないかと疑われます。

投稿日時 - 2009-05-16 11:59:29