C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 文字と数字の区別


(過去ログ 61 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■35076 / inTopicNo.1)  文字と数字の区別
  
□投稿者/ ドリア (1回)-(2009/04/19(Sun) 20:55:29)

分類:[C/C++] 

最近プログラミングを始めたばかりです。
「C/C++プログラミング初心者講座」さんを参考に、下のようなプログラムを書いてみました。
大体は想定通りいくのですが、初めのところで数値以外を入力すると無限ループができてしまいます。
意図としては、1,2,3以外を入力したら数値、文字にかかわらず「1 または 2 のいずれかを入力してください。」と出るようにしたいのですが・・・。
数値と文字の区別がイマイチできていません。
具体的にはどうすべきなのでしょうか?
ご教授お願いします。



#include <iostream>
#include <math.h>
#include <conio.h>

using namespace std;

int main()
{
// 動作の選択
	int select;
	double a,b,c;

	do{

	cout << "求めたいものを数字で選択してください。" <<endl;
	cout << "1. 三角形の面積" <<endl;
	cout << "2. 2次方程式の解" <<endl;
	cout << "3. 終了" <<endl;
	cout << "選択:";
	cin >> select;

	if(select==1)
	{
	// 三角形の面積

		cout << "求めたい三角形ABCの三辺a,b,cの値を入力してください。" <<endl;
		cout << "a="; cin >> a;
		cout << "b="; cin >> b;
		cout << "c="; cin >> c;

		if(fabs(a-b)<c && c<(a+b))
		{
		double cos,sin;
			cos = (a*a + b*b - c*c) / (2*a*b);
			sin = fabs(sqrt(1-cos*cos));

			double s;
			s = a * b * sin /2;

			cout << "3辺の長さが" << a << "," << b << "," << c;
			cout << "である三角形の面積は" << s << "である。" ;
		}
		else
		{
			cout << "そのような三角形は存在しません。";
		}

	}

	else
	{

		if(select==2)
		{
		//2次方程式の解
			cout << "2次方程式 ax^2+bx+c=0 の定数a,b,cの値を入力してください。" <<endl;
			cout << "a="; cin >> a;
			cout << "b="; cin >> b;
			cout << "c="; cin >> c;

			double d,r,kai1,kai2;
			d = b*b-4*a*c;

			cout << "2次方程式 "; if(a==1){;}else{cout<<a;} cout <<"x^2" ; 
			cout.setf(ios::showpos);
			if(b==1){;}else{if(b==-1){cout<<"-";}else{cout<<b;}}
			cout << "x" << c << "=0 の実数解は、";

			cout.unsetf(ios::showpos);
			if(d<0)
			{
				cout << "解なし である。";
			}

			else
			{
				r = sqrt(d);
				kai1=(-b-r)/(2*a);
				kai2=(-b+r)/(2*a);

				if(d==0)
					cout << "x=" << kai1 << "(重解)である。";
				else
					cout << "x=" << kai1 << " , " << kai2 << "である。";
			}

		}

		else
		{
			cout << "1 または 2 のいずれかを入力してください。";
		}

	}

			cout << endl << endl;
	}while(select != 3);
	

}

引用返信 編集キー/
■35077 / inTopicNo.2)  Re[1]: 文字と数字の区別
□投稿者/ επιστημη (1892回)-(2009/04/19(Sun) 21:09:24)
επιστημη さんの Web サイト
> 大体は想定通りいくのですが、初めのところで数値以外を入力すると無限ループができてしまいます。

> int select;
> cin >> select;

selectが数値(int)だからです。文字列に取り換えて試してみて。

引用返信 編集キー/
■35078 / inTopicNo.3)  Re[2]: 文字と数字の区別
□投稿者/ ドリア (2回)-(2009/04/19(Sun) 22:01:47)
素早い返信ありがとうございます。
文字列というのはcharのことでしょうか?

ためしに
char select;
として実行してみましたが、今度は最初に何を入力しても初めに戻ってしまいます;

どうすればよろしいでしょうか?
初歩的な質問ですみません。

引用返信 編集キー/
■35079 / inTopicNo.4)  Re[3]: 文字と数字の区別
□投稿者/ 774RR (342回)-(2009/04/19(Sun) 22:47:27)
scanf も cin >> も、その動作の仕様として「改行までを読み込むではない」のに対して
ドリア氏のやりたいことはたぶん「改行までを読み込む」のだと思われるのだが、違う?

int x; に対して cin >> x; と書いた場合の動作仕様は
・先頭側にあるスペース類文字(スペース、タブ、改行)があれば、捨てる
・整数として解釈できる文字が継続している限りにおいて取り込みを行い、整数値とする
・整数として解釈できない文字が現れたら、その文字は今回の処理では扱わず次回に回す

最初に123<CR>と入力した場合の動作を解説するなら、
・項2に従い123を取り込む
・項3に従い改行文字を処理せず残す
次回に456<CR>と入力したら
・項1に従い残っている改行文字を捨てる
・項2に従い456を取り込む
・項3に従い改行文字を処理せず残す

さらにa<CR>と入力したら
・項1に従い残っている改行文字を捨てる
・項2に従いaが数値として解釈できないので、取り込みに失敗し
・項3に従いaを残す (同時に改行も残る)
無限ループになるわけだ。

で、何をどう直せば「期待通り」の動作になるか?なんだが、実は結構難しい。
少なくとも cin >> を使う限りはあまりいい感じにならないのだ。
getline で string に取り込み stringstream で分析するのがよさそう。
引用返信 編集キー/
■35080 / inTopicNo.5)  Re[4]: 文字と数字の区別
□投稿者/ ドリア (3回)-(2009/04/19(Sun) 22:59:07)
2009/04/19(Sun) 23:00:20 編集(投稿者)

774RRさん、詳しい解説ありがとうございます。

・・・とはいっても今の僕の知識ではまだなかなか理解できそうにありません。
cin >>の仕様や、紹介してくださった
getline,string,stringstream
などについても、もっと勉強してからやってみることにします。



直接的に問題の解決はしていませんが、教えてもらったことをヒントにまずは基本を学ぶ、ということで、「解決済み」にしておきます。
お二人とも回答ありがとうございました。
解決済み
引用返信 編集キー/
■35081 / inTopicNo.6)  Re[3]: 文字と数字の区別
□投稿者/ επιστημη (1893回)-(2009/04/19(Sun) 23:06:44)
επιστημη さんの Web サイト
↓ざっくりといぢくってみた。

#include <iostream>
#include <cmath>
#include <string>

using namespace std;

int main() {
  string select;
  do{
    cout << "求めたいものを数字で選択してください。" <<endl;
    cout << "1. 三角形の面積" <<endl;
    cout << "2. 2次方程式の解" <<endl;
    cout << "3. 終了" <<endl;
    cout << "選択:";
    cin >> select;

    if ( select.size() == 0 ) continue;
    switch ( select[0] ) {
    case '1': { // 三角形の面積
      cout << "求めたい三角形ABCの三辺a,b,cの値を入力してください。" <<endl;
      double a,b,c;
      cout << "a="; cin >> a;
      cout << "b="; cin >> b;
      cout << "c="; cin >> c;

      if ( fabs(a-b) < c && c < (a+b) ) {
        double cos = (a*a + b*b - c*c) / (2*a*b);
        double sin = fabs(sqrt(1-cos*cos));
        double s   = a * b * sin / 2;
        cout << "3辺の長さが" << a << "," << b << "," << c;
        cout << "である三角形の面積は" << s << "である。" ;
      } else {
        cout << "そのような三角形は存在しません。";
      }
      break;
      }
    case '2' : { //2次方程式の解
      cout << "2次方程式 ax^2+bx+c=0 の定数a,b,cの値を入力してください。" <<endl;
      cout << "a="; cin >> a;
      cout << "b="; cin >> b;
      cout << "c="; cin >> c;

      double d = b*b-4*a*c;
      cout << "2次方程式 "; 
      if ( a != 1 ) {
        cout << a;
      }
      cout <<"x^2";
      cout.setf(ios::showpos);
      if ( b != 1 ) {
        if ( b==-1 ) {
          cout << "-";
        } else {
          cout << b;
        }
      }
      cout << "x" << c << "=0 の実数解は、";
      cout.unsetf(ios::showpos);
      if ( d < 0 ) {
        cout << "解なし である。";
      } else {
        double r = sqrt(d);
        double kai1=(-b-r)/(2*a);
        double kai2=(-b+r)/(2*a);
        if ( d==0 ) {
          cout << "x=" << kai1 << "(重解)である。";
        } else {
          cout << "x=" << kai1 << " , " << kai2 << "である。";
        }
      }
      break;
      }
    case '3' :
      break;
    default:
      cout << "1 または 2 のいずれかを入力してください。";
      break;
    }
    cout << endl << endl;
  } while ( select[0] != '3' );
}

解決済み
引用返信 編集キー/
■35137 / inTopicNo.7)  Re[4]: 文字と数字の区別
□投稿者/ ドリア (4回)-(2009/04/20(Mon) 23:56:06)
επιστημηさん、わざわざありがとうございます。

書いてくださったコードとにらめっこしながら勉強してみます。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -