ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

プログラマたまごくらぶコミュの【C++】Ifelse文の作成が上手く出来ません(´Д`;)

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めまして。
現在、C++を勉強しているのですが、上手くIfelse文が組み立てれません(汗
今回出された課題なのですが、テキストファイルから括弧を読み込んでちゃんとペアが見つかるかどうかを試すプログラムです。
例えば()、[]、([)]などはペアが成立してる、と結果が表示され、
別の場合は閉じ括弧がない、などの結果を表示させたいのです。

現在、Classなどは出来たのですが、メインの部分のIfelse文が出来てません。

どうか助けてください、よろしくお願いします。

#include "utmutility.hpp" //Special version of the utility file
#include "Stack.hpp"

int main()
{
Stack openings;
char symbol;
bool is_matched = true;
ifstream dataIn;

dataIn.open("assignment2.txt");
file_check(dataIn);

while(!dataIn.eof())
{
dataIn >> symbol;

while(is_matched && symbol != '\n'){
if(symbol == '{' || symbol == '(' || symbol == '[')
openings.push(symbol);

dataIn >> symbol;

if(symbol == '}' || symbol == ')' || symbol == ']'){
if(openings.empty()){
cout << "Unmatched closing bracket: " << symbol
<< " detected." << endl;
is_matched = false;
}

else{
char match;
openings.top(match);
openings.pop();
is_matched = (symbol == '}' && match == '{')
|| (symbol == ')' && match == '(')
|| (symbol == ']' && match == '[');
if(!is_matched)
cout << "Bad match: " << match << symbol << endl;

}

}

}
if(!openings.empty())
cout << "Unmatched opening bracket(s) detected." << endl;

}
pause();

return 0;
}

#ifndef STACK_HPP
#define STACK_HPP

#include "utmutility.hpp"

const int maxstack = 500;
typedef char Stack_entry;

class Stack{
public:
Stack();
bool empty() const;
Error_code pop();
Error_code top(Stack_entry &item) const;
Error_code push(const Stack_entry &item);

private:
int count;
Stack_entry entry[maxstack];
}; // class

#endif

#include "Stack.hpp"

Stack :: Stack()
/*Pre: None.
Post: The stack is initialized to be empty.*/
{
count = 0;
}

bool Stack :: empty() const
/*Pre: None.
Post: If the Stack is empty, true is returned. Otherwise false is returned.*/
{
bool outcome = true;
if(count > 0)
outcome = false;

return outcome;
}

Error_code Stack :: push(const Stack_entry &item)
/*Pre: None.
Post: If the Stack is not full, item is added to the top of the Stack. If the
Stack is full, an Error_code of overflow is returned and the Stack is left
unchanged.*/
{
Error_code outcome = success;
if(count >= maxstack)
outcome = overflow;
else
entry[count++] = item;

return outcome;
}

Error_code Stack :: pop()
/*Pre: None.
Post: If the Stack is not empty, the top of the Stack is removed. If the Stack
is empty, an Error_code of underflow is returned.*/
{
Error_code outcome = success;
if(count == 0)
outcome = underflow;
else
--count;

return outcome;
}

Error_code Stack :: top(Stack_entry &item) const
/*Pre: None.
Post: If the Stack is not empty, the top of the Stack is returned in item. If
the Stack is empty an Error_code of underflow is returned.*/
{
Error_code outcome = success;
if(count == 0)
outcome = underflow;
else
item = entry[count - 1];

return outcome;
}

#ifndef UTMUTILITY_HPP
#define UTMUTILITY_HPP

#include <iostream> // defines cout and cin
#include <fstream> // file input/output
#include <iomanip> // useful io manipulator functions setw etc.
#include <cstdlib> // conversion routines and system() calls
#include <cmath> // math functions like pwr(x,y)
#include <cctype> // char functions
#include <string> // string functions
#include <climits> // numeric limits
#include <cstddef> // C library language support
#include <ctime> // date and time functions
// all above from current Standard ANSI/ISO C++
using namespace std; // allows us to use the ANSI/ISO functions without
// the :: notation

// function prototypes
void file_check( ifstream &); //From Roux -- accepts filename and stops
// program if file cannot be opened.
void pause(); //From Roux -- pauses program and waits for a
// key to be pressed.
void clrscr(); //From Roux -- clears the command window.
bool user_says_yes(); //From Kruse & Ryba -- asks for y/n answer.

enum Error_code {success, fail, range_error, underflow, overflow, fatal,
not_present, duplicate_error, entry_inserted, entry_found,
internal_error};

#endif

#include "utmutility.hpp"

//////////////////////////////////////////////////////////////////
void file_check( ifstream &filename ) /// Stops program if no input file
{
if (!filename)
{
cout << "Problem opening input file." << endl;
pause(); // pause function must be here
exit(1);// Halt the program
}
}// end of file_check function

void pause() ///// Pause until a key is pressed.
{
system("pause"); // from cstdlib

}// end of pause()

void clrscr() //// Clear the screen
{
system("cls"); // from cstdlib
} // end of clrscr()

bool user_says_yes() // function is from Kruse & Ryba, Appendix C
{
int c;
bool initial_response = true;
do { // Loop until appropriate input is received.
if (initial_response)
cout << " (y/n)?" << flush;
else
cout << "Respond with either y or n: " << flush;
do { // Ignore white space
c = cin.get();
} while (c == '\n' || c == ' ' || c == '\t' );
initial_response = false;
} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N' );
return (c == 'y' || c == 'Y');

} // end of user_says_yes()

コメント(2)

2ヶ月以上経過していますが、もう解決されましたでしょうか? 実際プログラムを動かしていないので、動くかどうかは別にして以下のように書かれるとスマートだと思います。


while(!dataIn.eof())
{
dataIn >> symbol; //これをループの中で何回も呼び出すとeofを調べる意味が無い


//確かchar型の条件分岐の場合はif文以外にswitch文も使用できる

if(symbol == '{' || symbol == '(' || symbol == '[') //開き括弧の場合
openings.push(symbol);
else if(symbol == '}' || symbol == ')' || symbol == ']') //閉じ括弧の場合
{
if(openings.empty())
{
cout << "Unmatched closing bracket: " << symbol << " detected." << endl;
continue;//次のループへジャンプ
}

char match;
openings.top(match);
openings.pop();
is_matched = (symbol == '}' && match == '{')
|| (symbol == ')' && match == '(')
|| (symbol == ']' && match == '[');
if(!is_matched)
{
cout << "Bad match: " << match << symbol << endl;
continue; //次のループへ
}

//cout << "Match: "<< match << symbol; //合致したことを表示する

}
else if(symbol == "\n" && !openings.empty()) //行の終わりに達してもスタックが空ではない場合
{
cout << "Unmatched opening bracket(s) detected." << endl;
//ここでスタックの内容を空にしないと次からどんどんエラーになるのでは?
continue; //次のループへ
}
}
あと、if文の{}で囲む範囲をなるべく少なくするのも可読性の高いソースコードを書くためのポイントです。

ソースの下のほうになると、}が大量に出現して、どれがどのif文の終わりなのか分からなくなってしまいます。したがって、
if(異常な値)
{
cout << "エラーですよ\n";

}
else
{
hogehoge();//通常の処理
hogehoge2();
}

とするよりもこまめに、
if(異常な値)
{
cout << "エラーですよ\n";
return;
}
hogehoge();//通常の処理
hogehoge2();

というようにreturnやbreakやcontinueといった制御文を積極的に使うとコードがスマートになります。

こうすることでエラーの発見もしやすくなると思います。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

プログラマたまごくらぶ 更新情報

プログラマたまごくらぶのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング