2012-07-29 5 views
0

파일 처리에 C++ 문자열을 사용하는 방법은 무엇입니까? 개인 데이터 멤버 중 하나 인 C++ 문자열을 가진 클래스를 만들었지 만, 그 순간에 조작하지 않고 생성자에서 기본값으로 초기화 되어도 파일에서 읽는 동안 오류가 발생했습니다. 파일에 쓰는 동안 문제는 없습니다. 대신 C 문자열을 사용하면 잘 작동하지만 원하지 않습니다. 이 문제를 해결할 방법이 있습니까?파일 처리시 C++ 문자열 사용

class budget 
{  
    float balance;  
    string due_name,loan_name;    //string objects 
    int year,month;  
    float due_pay,loan_given;  

    public:     
    budget()  
    {  
      balance=0; 
      month=1;   
      due_name="NO BODY";    //default values 
      loan_name="SAFE"; 
      year=0;    
      balance = 0;  
      due_pay=0;   
      loan_given=0;  
    } 
     . 
     . 
     . 
}; 

void read_balance()    //PROBLEM AFTER ENTERING THIS FUNCTION  
{   
    system("cls");   
    budget b;  
    ifstream f1;  
    f1.open("balance.dat",ios::in|ios::binary);  
    while(f1.read((char*)&b,sizeof(b)))  
    { b.show_data();  
    }  
    system("cls");   
    cout<<"No More Records To Display!!";  
    getch();  
    f1.close();  
} 
+7

당신이 말하는 것에 대한 샘플을 제공해 주시겠습니까? – chris

+0

그래서 http://whataveyoutried.com/? –

+0

"오류"란 무엇입니까 –

답변

1

문자열은 non-POD data-type입니다. 읽기/쓰기 기능으로 문자열을 읽거나 쓸 수 없습니다.

basic_istream<charT,traits>& read(char_type* s, streamsize n); 
30

효과 ( 27.7.2.3, 제 1 항에 기재된 바와 같이) 포맷되지 않은 입력 함수로서 행동한다. 센트리 객체를 생성 한 후,! good()이 setstate (failbit)를 호출하면 예외가 발생하고 돌아올 수 있습니다. 그렇지 않으면 문자를 추출하여 첫 ​​번째 요소가 s.323으로 지정된 배열의 배열 위치에 저장합니다. 다음 문자 중 하나가 추출 될 때까지 문자가 추출되어 저장됩니다. - n 문자가 저장됩니다. - 파일 끝은 시퀀스 (이 경우 함수는 setstate (failbit | eofbit), 을 호출하며 ios_base :: failure (27.5.5.4)를 throw 할 수 있음)에서 발생합니다. 31 반환 값 : * this.

std::string의 회원은 어떻게 등록하나요? 또는 boost::serialiation을 사용하십시오. http://www.boost.org/doc/libs/1_50_0/libs/serialization/doc/index.html 물론 문자열의 크기를 쓰고 데이터를 쓸 수 있으며 읽기 - 읽기 크기 일 때이 크기의 배열을 할당하고이 배열에서 데이터를 읽은 다음 문자열을 만듭니다. 하지만 부스트를 사용하는 것이 좋습니다.

0

클래스 예산의 문자열 멤버 (due_name, loan_name)를 읽는 동안 코드는 말 그대로 바이트 단위로 채 웁니다. 부동 소수점과 정수는 의미가 있지만 문자열에는 사용할 수 없습니다.

문자열은 '무제한'텍스트 양을 유지하도록 설계되었으므로 생성자, 복사 생성자, 연결 등은 텍스트를 저장하고 필요한 경우 확장하기 위해 실제 메모리 조각을 할당해야합니다.). 디스크에서 이런 식으로 문자열을 채우면 문자열 객체 안에 잘못된 포인터가 생기고 실제로 텍스트는 실제로 이런 식으로 읽히지 않습니다.

0

이 문제를 해결하는 가장 쉬운 방법은 해당 클래스에서 C++ 문자열을 사용하지 않는 것입니다. 저장하려는 각 문자열의 최대 길이를 계산하고 1 바이트 길이의 char 배열을 만듭니다 (0 종결자를 허용). 이제 직렬화에 대해 걱정하지 않고이 클래스를 바이너리로 읽고 쓸 수 있습니다.

그렇게하고 싶지 않으면 클래스에서 iostream :: read()를 사용할 수 없습니다. 스트림에 읽고 쓸 수있는 멤버 함수가 필요합니다. 이것은 직렬화에 관한 것입니다 ... 그러나 부스트의 복잡성을 필요로하지 않습니다. 기본 용어, 당신은 뭔가를 할 거라고 :

// Read with no error checking :-S 
istream& budget::read(istream& s) 
{ 
    s.read((char*)&balance, sizeof(balance)); 
    s.read((char*)&year, sizeof(year)); 
    s.read((char*)&month, sizeof(month)); 
    s.read((char*)&due_pay, sizeof(due_pay)); 
    s.read((char*)&loan_given, sizeof(loan_given)); 

    size_t length; 
    char *tempstr; 

    // Read due_name 
    s.read((char*)&length, sizeof(length)); 
    tempstr = new char[length]; 
    s.read(tempstr, length); 
    due_name.assign(tempstr, length); 
    delete [] tempstr; 

    // Read loan_name 
    s.read((char*)&length, sizeof(length)); 
    tempstr = new char[length]; 
    s.read(tempstr, length); 
    loan_name.assign(tempstr, length); 
    delete [] tempstr; 

    return s; 
} 

ostream& budget::write(ostream& s) 
{ 
    // etc... 
} 

공지 사항 우리가 그 많은 문자 후 먼저 크기 값을 작성하고하여 문자열을 연재 한 그 위의

.