C++のプログラム中、疑問に思ったことがありましたので質問させていただきます。
 下記のプログラムを実行するとエラーになります。その原因をご存知の方がおりましたら教えてください。

 char* str;
cin >> str;
cout << str;
cout << endl;

 これを void main() などに書きまして実行するとエラーが出ます。
 [str]が配列の数を指定していないので無限に文字を入力でき、それを表示させるという簡単なプログラムですが、[str]をこのように使うとエラーになるのはなぜでしょうか。プログラムに詳しい人に聞いても『そういう仕組みだからそうなるのだろう』と言われるだけです。
 普通、[str]を使うとき、[ ]を使って配列で使うのだと思いますが、『無限に文字を入力できる』ように、上のパターンでプログラムを書くとエラーが出るのはなぜなのかよくわかりません。
 もしご存知の方がおりましたらお教えください。
 よろしくお願いいたします。

A 回答 (4件)

char* str;


はchar型のポインタを入れておく変数の宣言で、
そのままではゴミが入ってます。
int i;
と一緒でそれだけでは意味をなしません。
i = 10;
と初期化するのと同様に、strにも何か入れないといけません。
例えば、
char buf[10];
str = buf;
等です。

無限に文字を入力させるには、
文字を一文字づつ取ってきてて、領域がいっぱいになったら
その都度拡張させるような仕組みにしなければいけません。
    • good
    • 0
この回答へのお礼

やはり絶対に初期化することは必要なのですね。
初期化しなくても使えるのかどうか試してみたわけです。
また、本当にわからなかったことは、このエラーが『不正な処理』というメッセージになるのがなぜかということでした。
不正な処理として強制終了のようになることが疑問に思ったので質問させていただいたわけです。
ですが、お答えいただいたことはとても参考になりましたので感謝しております。
ありがとうございました。

お礼日時:2001/09/09 00:27

エラーの理由に関しては皆さんのおっしゃる通りだと思います。



batacha さんが、上のようなコードが正しいと思った原因は、おそらく、
配列とポインタとの違いがよくわかっていないからではないでしょうか。
配列 a[n] の配列名 a はポインタに似た性質を持ちますが、
(char型だとして) char* a; 等で宣言されるポインタ変数とは異なる
ものだと言うことに注意が必要です。

下の参考URLの第6章が参考になるかと思います。他にも疑問が湧いた場合
はまず下のページを覗いてみると良いかもしれません。

また、せっかくC++を使っているのならstring型を使えばbatachaさんが
やりたいことが実現できますよ。これについては適当なテキストを参考に
してみてください。

参考URL:http://www.catnet.ne.jp/kouno/c_faq/
    • good
    • 0
この回答へのお礼

文面からかなりお詳しい方だと思いました。
ポインタに関しては勉強しなおすことにいたします。
下記のお礼に書きましたように、最初なぜ質問しようと思ったのかといいますと、『不正な処理』というエラーメッセージが出たからでした。
ですが、皆さんのお答えから『初期化』というものが絶対に必要であるということがよくわかりました。
お答えいただいた皆さんに感謝しております。
ありがとうございました。

お礼日時:2001/09/09 00:33

> [str]が配列の数を指定していないので無限に文字を入力でき



とありますが、指定が無いと無限に入力できるというのが
そもそも間違いです。
無限に文字を入力し保存できるような物はこの世にありません。

また、このような書き方をすると無限どころか、
入力できるところが一つも無い状態になります。

普通に、配列を使ってください。


どうしても、無限にしたいのなら、
一文字分だけ入力して、一文字出力を無限に繰り返すことなら可能なので,
そうプログラムしてください。
繰り返しだけなら,論理上無限にできますから。
    • good
    • 0
この回答へのお礼

やはり配列を作らないとダメということですね。
ごもっともです。初期化は必要だと言うことがよくわかりました。
ご指摘ありがとうございました。

お礼日時:2001/09/09 00:29

C++は分からないのですが



Cだと分かるので(一応Cは専門家なので)
ポインタ宣言しただけだとポインタの格納領域を取っただけで
ポインタが指し示す領域は生成されないです。
C++だと
char* str;でポインタ宣言しただけで
入力文字を格納する領域も生成されるのでしょうか。
あ~、逆に質問になっている。すいません。気にしないで下さい。
    • good
    • 0
この回答へのお礼

御礼が遅くなり申し訳ありませんでした。
[C]の専門家なのですね。ポインタは[C]も共通してますからアドバイスはとても参考になりました。
 ありがとうございました。

お礼日時:2001/09/09 00:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qstd::cout << p と std::cout << *p の違

std::cout << p と std::cout << *p の違いは?

VC++でコードを書きながらC++を学んでいます。
ポインタで疑問に思ったことがあるので質問させて下さい。

int* p;
int n = 100;
p = &a;

上記のように変数を宣言・代入した場合、
std::cout << p と std::cout << *p のどちらでも"100"と表示されます。
これら二つの違いは何でしょうか?
本来*pとすべきところをpにしてもVC++が気を利かせて
&pのアドレスに入っているデータを表示してくれているということでしょうか?

Aベストアンサー

No.1氏の回答にあるコードを元に答えます。

>この場合&pでもアドレスが表示されると思うのですが、
>「&p」と「p」の違いは何でしょうか?
pはaのアドレス。
&pはpのアドレス。
(「p = &a」では、どこのアドレスを渡しているのか考えてみて下さい)


「&p」と「p」の違いというのが参照とポインタの違いを聞いているのだとしたら、constのポインタ==参照型で良かったと思います。
p = &a; //OK
&a = p; //error
int* const p2 = p;
p2 = &a; //error

Q&str[n]とpstr + nと&pstr[n]

あるプログラミングの本で

&str[n]
pstr + n
&pstr[n]

は同じだと書いてあり、考えたのですが、
上の二つはstr[n]のアドレスを表しているとしても、
三つ目はstr[n]のポインタのアドレスを表していると思うのですが
どこが間違っているのでしょうか?教えてください。

Aベストアンサー

>本にも突然でてきているのでよくわからないのですが・・・。

よくわからないもの同士が同じかと聞かれても、よくわからないというのが答えです。
本当に、突然出てきているのなら、そんな本は捨てましょう。

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

QC++ : cout << (数字) で実行時エラーが発生する理由

ある特定の位置でcout を用いて数字を表示しようとするとエラーが発生してしまいます。

具体的には以下の関数内でのことなのですが、原因の分かる方がいましたら解答お願いします。

受け取った文字列を逆順にする関数です。



----------------------------------------------------------

void rev_str(char *a)
{
int length = 0;


cout << length; // ここでエラーが発生


while(true) {
if(*(a + length) == '\0') break;
length++;
}
for(int i = 0; i < length / 2; i++) {
char temp = a[i];
a[i] = a[length - i - 1];
a[length - i - 1] = temp;
}
}



---------------------------------------------------------


エラーの発生する部分ですが、数字ではなく文字・文字列なら問題なく表示されます。

このコードでは変数 length を表示しようとしていますが、length でなくても、またどのような『数』でも『この関数内』で cout を使用するとエラーが発生します。

この関数に何か間違いがあるのではないかと思うのですが、どうにも見つけることが出来ません。
コード全体はこの下に掲載します。

cout に何か制約があるのでしょうか。それとも、やはりコードのどこかに誤りがあるのでしょうか。わかる方がいましたら、解答お願いします。




全コード
------------------------------------------------------
#include <iostream>
#include <cstring>
using namespace std;

void rev_str(char *a);
void rev_str(const char *source, char *des);

int main()
{
char a[80], b[80];
strcpy(a, "hello, world!");
rev_str(a, b);
rev_str(a);
cout << a << "\n";
cout << b << "\n";

return 0;
}

void rev_str(char *a)
{
int length = 0;

cout << length;

while(true) {
if(*(a + length) == '\0') break;
length++;
}
for(int i = 0; i < length / 2; i++) {
char temp = a[i];
a[i] = a[length - i - 1];
a[length - i - 1] = temp;
}
}

void rev_str(const char *source, char *des)
{
char *a = (char*)malloc(sizeof(source));
strcpy(a, source);
rev_str(a);
strcpy(des, a);
free(a);
}

ある特定の位置でcout を用いて数字を表示しようとするとエラーが発生してしまいます。

具体的には以下の関数内でのことなのですが、原因の分かる方がいましたら解答お願いします。

受け取った文字列を逆順にする関数です。



----------------------------------------------------------

void rev_str(char *a)
{
int length = 0;


cout << length; // ここでエラーが発生


while(true) {
if(*(a + length) == '\0') break;
length++;
}
for...続きを読む

Aベストアンサー

> void rev_str(const char *source, char *des)
> {
>  char *a = (char*)malloc(sizeof(source));
>  strcpy(a, source);
>  rev_str(a);
>  strcpy(des, a);
>  free(a);
> }
の中でmallocで確保されるサイズは sizeof(source)なので
char型のポインタサイズ ... 32Bit環境なら4バイトってことになります
その領域に対して strcpyを実行するので4バイト以上の文字列をコピーすればメモリー領域が破壊されます

NULL終端の文字列が対象なら
char *a = (char*)malloc( strlen( source ) );
といった具合に変更してみましょう

Qchar c = 'a'; char h[1] = c; エラー

char型のものを char[]型に代入したいです。

char c = 'a';
char h[1] = c;

として、

h[0] は \x97
h[1] は \x00

にしたいです。
型変換の方法を教えてください。

Aベストアンサー

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数を確保します。
後半で、その中を初期化しています。
添え字は 0 からはじまるので、この場合、h[0] に c の内容が代入されます。
1個しか場所を確保していないので、 h[1] の位置のデータは内容が不定です。
文字列として h を扱いたいのであれば、 C の文字列には終端として 0 が必要ですから、
char c = 'a';
char h[2] = { c, '\0'};

のような書き方が必要になります。
これで、お望みのデータになると思います。

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数...続きを読む


人気Q&Aランキング

おすすめ情報