2009-07-18 4 views
0

사용자가 책의 ISBN 번호를 입력 할 때 이미 저장되어있는 경우 오류 메시지가 출력되는 데이터 유효성 검사 양식을 입력하려고합니다. 그러나, 나는 이것을하는 데 문제가 있습니다. == 연산자를 올바르게 오버로드하고 있는지 잘 모르겠습니다. store_ISBN() 함수의 벡터 값을 비교하는 방법을 모르겠습니다. 내가하는 방법을 알아 내기 전에 모든 일을 입력하지 않기 때문에 store_ISBN 기능에 난 단지 하나 개의 변수에 대한 테스트를 포함했다고벡터의 값을 입력 값과 비교

#include "std_lib_facilities.h" 

// Classes --------------------------------------------------------------------- 

class Book{ 
public: 
     vector<Book> books; // stores book information 
     Book() {}; // constructor 
     friend ostream& operator<<(ostream& out, const Book& b); 
     bool operator==(const Book& d); 
     string what_title(); 
     string what_author(); 
     int what_copyright(); 
     void store_ISBN(); 
     void is_checkout(); 
private: 
     char check; 
     int ISBNfirst, ISBNsecond, ISBNthird; 
     char ISBNlast; 
     string title; 
     string author; 
     int copyright; 
}; 

// Class Functions ------------------------------------------------------------- 

string Book::what_title() 
{ 
     cout << "Title: "; 
     getline(cin,title); 
     cout << endl; 
     return title; 
} 

string Book::what_author() 
{ 
     cout << "Author: "; 
     getline(cin,author); 
     cout << endl; 
     return author; 
} 

int Book::what_copyright() 
{ 
    cout << "Copyright Year: "; 
    cin >> copyright; 
    cout << endl; 
    return copyright; 
} 

void Book::store_ISBN() 
{ 
    bool test = false; 
    cout << "Enter ISBN number separated by spaces: "; 
    while(!test){ 
    cin >> ISBNfirst >> ISBNsecond >> ISBNthird >> ISBNlast; 
    for(int i = 0; i < books.size(); ++i) 
      if(ISBNfirst == books[i]) cout << "test"; // no idea how to implement this line    
    if((ISBNfirst<0 || ISBNfirst>9) || (ISBNsecond<0 || ISBNsecond>9) || (ISBNthird<0 || ISBNthird>9)) 
        error("Invalid entry."); 
    else if(!isdigit(ISBNlast) && !isalpha(ISBNlast)) 
      error("Invalid entry."); 
    else test = true;}  
    cout << endl; 
} 

void Book::is_checkout() 
{ 
    bool test = false; 
    cout << "Checked out?(Y or N): "; 
    while(!test){ 
    cin >> check; 
    if(check == 'Y') test = true; 
    else if(check == 'N') test = true;         
    else error("Invalid value.");} 
    cout << endl; 
} 

// Operator Overloading -------------------------------------------------------- 

bool Book::operator==(const Book& d){ // is this right??? 
    if((ISBNfirst == d.ISBNfirst) && (ISBNsecond == d.ISBNsecond) 
      && (ISBNthird == d.ISBNthird) && (ISBNlast == d.ISBNlast)) return true; 
    else return false; 
} 

ostream& operator<<(ostream& out, const Book& b){ 
     out << "Title: " << b.title << endl; 
     out << "Author: " << b.author << endl; 
     out << "ISBN: " << b.ISBNfirst << "-" << b.ISBNsecond << "-" << b.ISBNthird << "-" << b.ISBNlast << endl; 
     out << endl; 
     return out; 
} 

// Main ------------------------------------------------------------------------  

int main() 
{ 
    Book store; 
    string question; 
    while(true){ 
     store.what_title(); 
     store.what_author(); 
     store.what_copyright(); 
     store.store_ISBN(); 
     store.is_checkout(); 
     store.books.push_back(store); 
     cout << "Are you finished?(Y or N): "; 
     cin >> question; 
     if(question == "Y") break; 
     else if(question == "N"){ 
       cout << endl; 
       cin.ignore();} 
     else error("Invalid value."); 
     } 
    cout << endl; 
    cout << "Books stored -\n" << endl; 
    for(int i = 0; i < store.books.size(); ++i) 
      cout << store.books[i]; 
    keep_window_open(); 
} 

참고 : 여기에

코드입니다 그것.

책이 메인의 루프를 통과 할 때마다 알 수 있듯이 해당 책의 데이터가 저장됩니다. 그런 다음 < < 연산자에 오버로드하여 제목, 작성자 및 ISBN을 인쇄하여 루프 이후의 모든 데이터 입력을 출력 할 수 있습니다. 그래서 나는 벡터의 개별 데이터에 액세스하여 사용자 입력 ISBN과 비교할 수 있어야한다고 생각하지만 어떻게해야할지 모르겠다. 내가 혼란스러워하는 부분은 그러한 것으로 주석 처리되었습니다.

+0

while 루프는 잘못된 형식입니다. while (true!) 대신 while (question! = "Y")를 사용하십시오. – jkeys

+0

또한 "무엇"접두사를 사용하지 않고 그냥 변수의 이름을 사용하십시오. 일반적인 규칙에 따라 모든 데이터 멤버를 "_"(예 : string title_;)로 추적 한 다음 밑줄없이 이름을 사용하여 해당 변수에 액세스해야합니다. – jkeys

답변

4

사용자가 ISBN을 입력하는 것으로 예상되는 내용이 확실하지 않습니다.

스트림을 int로 읽어 들이면 숫자가 공백까지 읽히고 결과가 int로 변환됩니다 (모두 잘되면 어쨌든). char 값을 읽으면 char 값을 저장합니다. 그래서 ISBN보다 유효성 검사를하는 순간 세 개의 단일 숫자 (0-9)와 다음 문자가 나타납니다. ISBN이 그렇게 생각하지 않습니다.귀하의 operator==

는 OK 보이지만 조건문이 이미 bool 형식의 때문에 부울 반환 값,

if (X) return true; 
else return false; 

return X; 

로 대체 할 수 있습니다.

당신의 ISBN 값 (그리고 아직 완성되어 있지 않은 경우는, operator==에 사용하려는 다른 필드)를 설정 한 후, 가게에서 일치하는 도서를 찾는 방법은 다음과 같습니다 다른에서

for(int i = 0; i < books.size(); ++i) 
    if(*this == books[i]) cout << "test"; 

단어,이 책과 같은 책을 찾습니다. 또는 std::find<algorithms>에서 사용할 수도 있지만이 경우에는 더 이상 간결하지 않습니다.

그런데 같은 책 (책)을 사용하여 독서와 전체 상점을 나타내는 것은 드문 일입니다. 피킹을 해제하는 것은 상당히 복잡한 변경과 결정입니다. 따라서 클래스는 단일 한 종류의 것을 나타내야하고, 클래스의 객체는 그러한 종류의 예를 나타냅니다. 그래서 보통 Book과 Bookstore는 다른 종류의 것입니다. Book의 벡터는 인스턴스 변수로서, 모든 Book에는 고유 한 Book 벡터가 있습니다. 그건 정말 말이되지 않습니다.

+0

각 책의 모든 데이터는 각 벡터 요소에 저장됩니다. 모든 도서에 대해 별도의 도서 개체를 만드는 것보다 더 나은 구현이라고 생각했습니다. 그러나 코드를 작성하지 않은 사람이 어떻게 혼란 스러울 지 알 수 있습니다. – trikker

+0

잠깐, 책이나 ints를 비교하려고합니까? 책을 책과 int를 int, 또는 책 -> int를 int와 비교할 수 있습니다. – jkeys

+0

이것은 실전 프로그램이 아니기 때문에 실사적인 ISBN을위한 책이 아니므로 책에 나와있는대로 문자 또는 숫자 3 자리를 물어 보았습니다.지금 당장 당신의 솔루션을 시험해 보겠습니다. – trikker

1

books는 Book 클래스의 벡터를 의미합니다. Book과 정수를 비교하는 것은 정의되지 않은 동작입니다. 데이터 멤버에 액세스하려면 먼저 Book 객체를 참조 해제해야합니다.

먼저 첨자 [] 표기법을 사용하여 벡터에 액세스하지 마십시오. 비효율적이며 삶을 어렵게 만듭니다. 그러나,

for (std::vector::iterator it = books.begin(); it != books.end(); ++it) 
{ 
} 

문제되지 않습니다 : 반복자 (같은, 구현하려는 것입니다 방법에 대한 확실하지)를 사용합니다. -> 연산자를 사용하여 오브젝트를 역 참조하여 멤버에게 전달하십시오. 당신은 그러나 당신의 회원이 비공개 때문에 (사람들이 데이터를 속일 수) 당신이 중 하나는

ISBNf() { return ISBNfirst; } 

아니면 회원 공개와 같은 get 함수를 필요로하지만 나쁜 생각이다. 그러나, 단순화를 위해, 그들은 공개되어 가정, 이것은 당신이 원하는 : 나는 당신이 달성하려고하는 무엇을 아무 생각이 없기 때문에

for (std::vector::iterator it = books.begin(); it != books.end(); ++it) 
{ 
    if (*this == *it) cout << "test"; 
} 

, 여기에, 더 좋은 해결책이 없습니다. 나는 당신이 정수의 자릿수를 비교하려고 노력하고 있다고 생각하지만, 이것은 그것을 성취하는 방법이 아닙니다. ISBNfirst를 올바르게 지정하고 있는지 확인하려면 마음을 쉬게하십시오. . 그러나, 당신은 어디 인, 올바르게 접근하지 않습니다 -> 연산자로 제공

다음이 코드는 과잉이다 : 대신

else if(!isdigit(ISBNlast) && !isalpha(ISBNlast) 

의 isalphnum() 함수를 사용

else if (!isalphnum(ISBNlast)); 

게시 됨; 내 게시물을 편집하여 코드의 모든 결함을 지적 할 것입니다.

+1

"벡터의 첨자 [] 표기법을 사용하지 않으므로 비효율적입니다. 신화. 인덱스를 통해 액세스하는 것은 이와 같은 상황에서 측정 할 수 없을 정도로 느리지 않으며 반복 코드보다 훨씬 간결합니다. –

+0

나를 연결시켜 주시겠습니까? iterators 사용을 중지하기 전에 몇 가지 증거를 갖고 싶습니다. 게다가, 역 참조 연산자가 훨씬 명확하고 깨끗하다고 ​​생각합니다. – jkeys

+0

또한 store_ISBN이 Book의 멤버 함수라는 것을 알았습니까? 따라서 접근 자나 공용 멤버 또는 멤버 변수에 액세스 할 필요가 없습니다. 디자인을 인정하는 것은 아니지만, 존재하지 않는 구문 문제를 주장한다고 생각합니다. '(* it) -> ISBNFirst'는 작동하지 않을 것입니다. Book은 Book의 벡터가 아니기 때문에 작동하지 않습니다. '(* it)'은 책이고,'(* it) .ISBNFirst는'필드에 접근하는 올바른 방법입니다. –

관련 문제