2010-03-08 3 views
7

다음은 아마도 여러분에게 매우 불쾌한 질문 일 것입니다 : 어떻게 (가능하다면) 함수에서 ifstream을 반환 할 수 있습니까?함수에서 ifstream 반환하기

기본적으로 사용자로부터 데이터베이스의 파일 이름을 가져와야하며 해당 파일 이름의 데이터베이스가없는 경우 해당 파일을 만들어야합니다. 그 방법을 알고 있지만 파일을 만든 후 사용자에게 프로그램을 다시 시작하도록 요청하면됩니다. 나는 사용자가 가능한 경우에 그 불편을 피하기 위해 싶었지만, 아래의 기능은 GCC의 컴파일되지 않습니다 :

ifstream getFile() { 
    string fileName; 
    cout << "Please enter in the name of the file you'd like to open: "; 
    cin >> fileName; 
    ifstream first(fileName.c_str()); 
    if(first.fail()) { 
     cout << "File " << fileName << " not found.\n"; 
     first.close(); 
     ofstream second(fileName.c_str()); 
     cout << "File created.\n"; 
     second.close(); 
     ifstream third(fileName.c_str()); 
     return third; //compiler error here 
    } 
    else 
     return first; 
} 

편집 : 죄송합니다, 어디 당신에게 잊고 컴파일러 오류가 무엇인지 :

main.cpp:45: note: synthesized method ‘std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const std::basic_ifstream<char, std::char_traits<char> >&)’ first required here 

편집 : Remus 제안 대신 포인터를 반환하도록 함수를 변경하고 main()의 줄을 "ifstream database = * getFile()"으로 변경했습니다. 지금은 다시 오류가 발생하지만, 주()의 라인이 시간 :

main.cpp:27: note: synthesized method ‘std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const std::basic_ifstream<char, std::char_traits<char> >&)’ first required here 
+3

나열된 것은 컴파일러 오류가 아니며 "메모"입니다. 실제 오류를보십시오. –

답변

5
bool checkFileExistence(const string& filename) 
{ 
    ifstream f(filename.c_str()); 
    return f.is_open(); 
} 

string getFileName() 
{ 
    string filename; 
    cout << "Please enter in the name of the file you'd like to open: "; 
    cin >> filename; 
    return filename; 
} 

void getFile(string filename, /*out*/ ifstream& file) 
{ 
    const bool file_exists = checkFileExistence(filename); 
    if (!file_exists) { 
     cout << "File " << filename << " not found." << endl; 
     filename = getFileName(); // poor style to reset input parameter though 
     ofstream dummy(filename.c_str(); 
     if (!dummy.is_open()) { 
      cerr << "Could not create file." << endl; 
      return; 
     } 
     cout << "File created." << endl; 
    } 
    file.open(filename.c_str()); 
} 

int main() 
{ 
    // ... 
    ifstream file; 
    getFile("filename.ext", file); 
    if (file.is_open()) { 
     // do any stuff with file 
    } 
    // ... 
}
+0

감사합니다 !!! 당신의 코드를 약간 수정 한 후에 나는 마침내 내가 원하는 것을 얻었습니다. : D – wrongusername

+1

이 코드 단편은 질문을 해결할 수 있지만 [설명 포함] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-base- answers) 정말 품질을 향상시키는 데 도움이됩니다. 귀하의 게시물의 앞으로 독자의 질문에 답하고 있으며 코드 제안의 이유를 알지 못할 수도 있습니다. – NathanOliver

3

ifstream은 당신이 ifstream를 반환 할 수 있도록 복사, 의미 (오류 메시지가 기본적으로 SAIS 그 무엇을) 구성을 지원하지 않습니다. 대신 ifstream *을 반환하고 호출자에게 할당 포인터를 삭제할 책임을 전달합니다.

+0

좋아요 ... 나는 "return & third"를 넣었고 이제는 "지역 변수 '3 번째 주소가 반환되었습니다."라고 경고합니다. main()에서 무엇을합니까? – wrongusername

+0

결코 반환하지 마십시오 & stack_variable. new 연산자로 ifstream을 할당하고 포인터를 반환하십시오. –

+0

"ifstream returnStream = &first; return returnStream;"과 같은 것을 의미합니까? btw도 작동하지 않습니다. 그것은 나에게 오류가 발생합니다 : "main.cpp : 56 : error : 'std :: ifstream *'에서 non-scalar type 'std :: ifstream'으로의 변환이 요청되었습니다. main.cpp : 57 : error : 'void *'에서 'std :: ifstream *'로의 변환이 잘못됨 " – wrongusername

14

아니요. ifstream에는 복사 생성자가 없으므로 반환하려는 경우 함수의 인스턴스를 반환해야하는 곳으로 복사하는 것이 좋습니다.

일반적인 해결 방법은 참조를 전달하고 함수에서 해당 참조를 수정하는 것입니다.

편집 : 코드가 작동하는 동안 기본 문제는 해결되지 않습니다. 지금은 하나의 기능으로 두 가지 다른 책임을 혼합하고 있습니다 : 1) 파일 이름을 얻으십시오. 2) 파일을 열거 나 작성하십시오. 코드를 분리하면 코드가 더 간단 해지고보고있는 문제의 원인을 훨씬 쉽게 제거 할 수 있다고 생각합니다.

편집 2 :이 같은 참조를 사용하면 operator=없이 완벽하게 작동합니다. 일반적인 생각은 다음과 같습니다 :

이 경우 할당 연산자가 필요하거나 유용하지 않습니다. 참조를 통해 기존 fstream을 사용하기 만하면됩니다. operator=일 경우에만 인수를 전달해야만합니다. 스트림을 사용하면 파일에 연결하지 않는 스트림을 기본으로 구성한 다음 open을 사용하여 사실 이후에 파일에 연결할 수 있습니다.

+0

고마워! 내가 그랬지.하지만 불행히도 코드는 여전히 작동하지 않아. "ifstream "main.cpp : 29 : note : synthetic 메쏘드"줄에 오류가 발생했습니다. std :: basic_ifstream :: basic_ifstream (const std :: basic_ifstream > &) '여기에서 첫 번째로 필요함' – wrongusername

+0

하지만 그 오류는 저를 하나의 오류로 처리했다고 생각합니다. – wrongusername

+0

새로운 객체를 반환하지 않기 위해 참조를 전달하는 "속임수" '오페라 (opera) '타입을 가진 작품 토르 ='. std :: ifstream도 그 중 하나를 가지고 있지 않으므로,이 조언은 당신을 위해 작동하지 않습니다. – MSalters