[C++ / 초보자 / 코드첨부] Switch - Case 문에서 무한로프를 도는 이유를 모르겠습니다.
조회수 2924회
현재 fstream 공부 하던 중 아래와 같이 앞글자 키워드를 입력하면 해당기능이 수행되는 프로그램을 만들어 보고 있는데요.
각 함수를 만들다가 막혀서 일단 테스트해보면서 만들어 나아가보려고 메인 함수부터 만들고 있습니다.
어찌된 일인지 'B'와 같이키워드를 입력하면 "hi" 와 같이 해당 케이스의 기능이 수행되는 것이 아니라 디폴트 케이스의 "Wrong Input" 이 무한으로 나옵니다. 코드를 어찌 고쳐야할까요?... 빠른 답변 주시면 감사하겠습니다.
(초보자인지라 글만 봐서는 이해가 잘 안가서 코드로 설명해주시면 더욱 감사하겠습니다 ㅎㅎ)
아래는 코드입니다.
//header.h
#include <iostream>
class BookData
{
public:
// default ClientData constructor
BookData(int = 0, const std::string & = "", int = 0, double = 0.0);
// accessor functions for lastName
void setProductNumber(int);
int getProductNumber() const;
void setProductName(const std::string &);
std::string getProductName() const;
void setQuantity(int);
int getQuantity() const;
void setPrice(double);
double getPrice() const;
private:
int ProductNumber;
char ProductName[15];
int Quantity;
double Price;
}; // end class ClientData
//header.cpp
#include <iostream>
#include "header.h"
BookData::BookData(int ProductNumValue,
const std::string &ProductNameString,
int QuantityValue,
double PriceValue)
: ProductNumber(ProductNumValue), Quantity(QuantityValue), Price(PriceValue)
{
setProductName(ProductNameString);
}
void BookData::setProductNumber(int ProductNumValue ) {
this->ProductNumber = ProductNumValue;
}
int BookData::getProductNumber() const {
return ProductNumber;
}
void BookData::setProductName(const std::string &ProductNameString) {
int length = ProductNameString.size();
length = (length < 15 ? length : 14);
ProductNameString.copy(ProductName, length);
ProductName[length] = '\0';
}
std::string BookData::getProductName() const {
return ProductName;
}
void BookData::setQuantity(int QuantityValue) {
this->Quantity = QuantityValue;
}
int BookData::getQuantity() const {
return Quantity;
}
void BookData::setPrice(double PriceValue) {
this->Price = PriceValue;
}
double BookData::getPrice() const {
return Price;
}
// source.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "header.h"
using namespace std;
void outputLine(ostream &output, const BookData &record) { // 출력시 단위 line
double total = record.getQuantity() * record.getPrice();
output << setfill(' ') << left << setw(10) << record.getProductNumber()
<< setw(15) << record.getProductName()
<< setw(15) << record.getQuantity()
<< setw(10) << record.getPrice()
<< setw(10) << total;
}
char enterChoice(void) {
char choice;
// 메뉴 문구를 수정하여도 문구가 자동으로 정렬되도록 하기위해 문구를 변수로 저장
string title = "Main Menu";
string menu_1 = "(S)how records on Screen";
string menu_2 = "(U)pdate a Book";
string menu_3 = "(A)dd a new Book";
string menu_4 = "(D)elete a Book";
string menu_5 = "(B)uild a File";
string menu_6 = "(Q)uit";
cout << endl;
cout << '\t' << setfill('-')
<< setw(18 + title.length() / 2)
<< title // 제목 출력(자동 가운데 정렬)
<< setw(18 - title.length() / 2)
<< ' ' << endl;
cout << '\t' << 'I' << setfill(' ') << setw(34) << 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ') << setw(16 + menu_1.length() / 2)
<< menu_1 // 메뉴 1 출력(자동 가운데 정렬)
<< setw(18 - menu_1.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ') << setw(16 + menu_2.length() / 2)
<< menu_2 // 메뉴 2 출력(자동 가운데 정렬)
<< setw(18 - menu_2.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ')
<< setw(16 + menu_3.length() / 2)
<< menu_3 // 메뉴 3 출력(자동 가운데 정렬)
<< setw(18 - menu_3.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ')
<< setw(16 + menu_4.length() / 2)
<< menu_4 // 메뉴 4 출력(자동 가운데 정렬)
<< setw(18 - menu_4.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ')
<< setw(16 + menu_5.length() / 2)
<< menu_5 // 메뉴 5 출력(자동 가운데 정렬)
<< setw(18 - menu_5.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I'
<< setfill(' ')
<< setw(16 + menu_6.length() / 2)
<< menu_6 // 메뉴 6 출력(자동 가운데 정렬)
<< setw(18 - menu_6.length() / 2)
<< 'I' << endl;
cout << '\t' << 'I' << setfill(' ') << setw(34) << 'I' << endl;
cout << '\t' << 'I' << setfill('-') << setw(34) << 'I' << endl;
/*do {
cout << "\n? ";
cin >> choice;
} while (choice != ('S' || 's' || 'U' || 'u' || 'A' || 'a' ||
'D' || 'd' || 'B' || 'b' || 'Q' || 'q'));*/
cout << '\t'; cin >> choice;
return choice;
}
void showRecords(fstream &input) {
ifstream inCredit("book.dat", ios::in | ios::binary);
if (!inCredit) {
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
}
cout << left
<< setw(10) << "BkNum"
<< setw(15) << "ProdNum"
<< setw(15) << "Quantity"
<< setw(10) << "Price"
<< setw(10) << "Total"
<< endl;
cout << setfill('-') << setw(60) << endl;
BookData record;
inCredit.read(reinterpret_cast <char *> (&record), sizeof(BookData));
while (inCredit && !inCredit.eof()) {
if (record.getProductNumber() != 0) {
outputLine(cout, record);
}
}
inCredit.read(reinterpret_cast <char *> (&record), sizeof(BookData));
//double totalAmount;
//cout << "Total Amount : " << totalAmount;
}
void updateRecord(fstream &output) {
int prodnum;
cout << "------------------EDIT RECORD------------------" << endl << endl;
cout << "Enter prod number to edit : " << prodnum;
}
void neweRecord(fstream &output) {
int productNum;
string productName;
int quantity;
double price;
fstream outCredit1("book.dat", ios::in | ios::out | ios::binary);
BookData record;
// exit program if fstream cannot open file
if (!outCredit1)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
} // end if
cout << "Enter product number (1 to 50, 0 to end input)" << endl << "?";
//cout << "Enter product number (1 to " << recordsize << ", 0 to end input)" << endl << "?";
cin >> productNum;
while (productNum > 0 && productNum <= 50) {
cout << "Enter product Name, quantity, price\n";
cin >> productName;
cin >> quantity;
cin >> price;
record.setProductNumber(productNum);
record.setProductName(productName);
record.setQuantity(quantity);
record.setPrice(price);
}
outCredit1.seekp((record.getProductNumber() - 1) * sizeof(BookData));
outCredit1.write(reinterpret_cast <const char *> (&record), sizeof(BookData));
cout << "Enter product number (1 to 50, 0 to end input)" << endl << "?";
//cout << "Enter product number (1 to " << recordsize << ", 0 to end input)" << endl << "?";
cin >> productNum;
}
void deleteRecord(fstream &out) {
}
void buildFile()
{
system("cls");
cout << "\n----------------BUILD THE FILE---------------------" << endl;
cout << "\nEnter number of records :";
int recordsize;
cin >> recordsize;
ofstream outCredit1("book.dat", ios::out | ios::binary);
// exit program if ofstream could not open file
if (!outCredit1)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
} // end if
BookData blankbook; // constructor zeros out each data member
/*cout<<sizeof(blankbook)<<endl;*/
// output blank records to file
for (int i = 0; i < recordsize; ++i)
outCredit1.write(reinterpret_cast<const char *>(&blankbook),
sizeof(BookData));
outCredit1.close();
} // end main
int main() {
char input = enterChoice();
while (input = ('S' || 's' || 'U' || 'u' || 'A' || 'a' || 'D' || 'd' || 'B' || 'b' || 'Q' || 'q'))
{
switch (input) {
case 'S' :
case 's' :
//
break;
case 'U' :
case 'u':
//
break;
case 'A':
case 'a':
//
break;
case 'D':
case 'd':
//
break;
case 'B':
case 'b':
cout << "hi";
//buildFile();
//enterChoice();
break;
case 'Q':
case 'q':
input = false;
break;
default:
cout << "Wrong Input" << endl;
break;
}
}
}
-
(•́ ✖ •̀)
알 수 없는 사용자
2 답변
-
default: cout << "Wrong Input" << endl; input = false; break;
위와 같이
input=false
를 추가해보세요.default
일 경우에도 종료하는 것이라면,Q
를 입력했을 때의 처리루틴이 포함되어야 합니다.그렇지 않은 경우라면, 새로운 입력(
input
이 변경안됨.)을 받는 루틴이 없어서 발생하는 문제입니다.- 답변 감사합니다. 시도해보았지만 여전히 같은 증상이 발생합니다ㅠㅠ 알 수 없는 사용자 2016.11.1 14:55
- 조건부분을 수정해보니 해결되었습니다. 조건 부분이 문제였던 것 같네요 ㅎㅎ 감사합니다. 알 수 없는 사용자 2016.11.1 16:30
-
먼저 질문자 분의 의도가
'Q' 혹은 'q' 를 입력 받기 전까지는 반복해서 입력을 받는다. 라면,
while 문 안에서 입력을 받아야 합니다.
그리고 'Q'혹은 'q'를 입력 받았아면, 반복문을 멈춰주시면 됩니다.
그리고 저도 c++안한지 오래돼서 잘모르겠지만.. while 문 안에 들어가는 조건문이 틀린것 같습니다.
위의 조건대로 main 함수를 수정해보면
int main() { char input; int flag = 1; while (flag) { input = enterChoice(); switch (input) { case 'S' : case 's' : // 'S' or 's' cout << "in s" << endl; break; case 'U' : case 'u': // 'U' or 'u' cout << "in u" << endl; break; case 'A': case 'a': // 'A' or 'a' cout << "in a" << endl; input = 'w'; break; case 'D': case 'd': // 'D' or 'd' cout << "in d" << endl; break; case 'B': case 'b': // 'B' or 'b' cout << "in b" << endl; cout << "hi"; //buildFile(); //enterChoice(); break; case 'Q': case 'q': // 'Q' or 'q' quit cout << "in q" << endl; flag = 0; break; default: // default cout << "Wrong Input" << endl; break; } } }
이렇게 하면 될 것 같습니다.
코드를 돌려보진 않아 오타가 있을 수 있고 기본적인 문법이 틀렸을 수도 있지만, 대략적으로 이렇게 돌아가는게 맞는것 같습니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
댓글 입력