2014-10-09 42 views
0

我正在學習文件流。在main之外的單獨函數中使用ifstream時遇到問題。內部主要它工作得很好。功能是這樣的,無法在單獨的函數中調用ifstream

void counter(string str) 
{ 
    ifstream inpufile(str,ios::in);//the error is here, it says the function cannot be called!?! 
    if(!inpufile) 
    { 
     cout<<"\n The file does not exist, try again"; 
    } 
    else 
    { 
     char c; 
     int counter=0; 
     while(inpufile.get(c)) 
     { 
      if(c=='\n') 
       counter++; 
     } 
     cout<<"\n The number of lines in the file are "<<counter+1; 
    } 
    inpufile.close(); 
} 

函數調用是從主(),並且是這樣

counter(argv[1]); 

我只能通過ifstream的作爲對象。我能否創建一個外部主體?

+0

您是否在'counter'文件中包含'#include '? – 2014-10-09 15:02:18

+0

是的,我做到了。它在文件的頂部。 – 2014-10-09 15:05:22

+0

你的代碼似乎沒有錯。你是否收到編譯錯誤或運行時錯誤? – Paulo1205 2014-10-09 15:06:39

回答

3

你的問題與函數沒有任何關係,它與保存文件名的變量有關。試想一下:

int main(int argc, const char** argv) 
{ 
    std::ifstream inpufile(argv[1], ios::in); // ok 

    std::string fname = argv[1]; // ok 
    std::ifstream fileb(str, ios::in); // fails pre-C++11 
} 

由於具有功能,你從const char*引起隱式轉換std::string,就像上面的例子。並且std::fstream在C++ 11之前沒有將std::string作爲文件名。兩種方法來解決:

void counter(const char* fname) 
{ 
    ifstream inpufile(fname, ios::in); // works now 

counter(argv[1]);仍然有效,其實它的工作原理一點點更好,因爲不需要轉換。

或者

void counter(std::string fname) 
{ 
    ifstream inpufile(str.c_str(), ios::in); // ok too 

它得到的const char*fstream預期。

C++ 11確實最終解決了這個問題,並讓您直接使用std::string

+0

謝謝,那完美的工作。 – 2014-10-09 15:13:51

1

是的,你可以在一個函數內創建它。該功能是正確的。

如果(在C++ 11之前)需要將std::string轉換爲char*,則可以使用c_str()

所以改變這樣的:

ifstream inpufile(str,ios::in);

這樣:

ifstream inpufile(str.c_str(),ios::in);

你可以做這樣的:

void counter(string str, ifstream& inpufile) { 
    if (!inpufile) { 
    cout << "\n The file does not exist, try again"; 
    } else { 
    char c; 
    int counter = 0; 
    while (inpufile.get(c)) { 
     if (c == '\n') 
     counter++; 
    } 
    cout << "\n The number of lines in the file are " << counter + 1; 
    } 
    inpufile.close(); 
} 

int main() { 
    string str = "Team.txt"; 
    ifstream inpufile(str.c_str(), ios::in); 
    counter(str, inpufile); 
    return 0; 
} 

您還可以創建文件對象在主要和打開它裏面e功能是這樣的:

void counter(string str, ifstream& inpufile) { 
    inpufile.open(str.c_str(), ios::in); 
    if (!inpufile) { 
    cout << "\n The file does not exist, try again"; 
    } else { 
    char c; 
    int counter = 0; 
    while (inpufile.get(c)) { 
     if (c == '\n') 
     counter++; 
    } 
    cout << "\n The number of lines in the file are " << counter + 1; 
    } 
    inpufile.close(); 
} 

int main() { 
    string str = "Team.txt"; 
    ifstream inpufile; 
    counter(str, inpufile); 
    return 0; 
} 

你的代碼給函數提供文件名,然後在函數內部創建文件對象。

+0

這正是我的問題,我可不只是傳遞一個文件名並在main()之外創建一個ifstream對象嗎? – 2014-10-09 15:03:52

+0

是的,您可以@SamEbenezer,是不是我的答案中的代碼是什麼?哦,也許你想在外面創建文件對象,然後在函數內部用文件名來提供它? – gsamaras 2014-10-09 15:05:13

+0

不,使用文件名提供函數,然後在函數內部創建文件對象。 – 2014-10-09 15:06:39

1
ifstream inpufile(str.c_str()); 

ios::in沒有必要,因爲它是隱式設置的。

+0

這個答案已被標記爲質量審查,因爲它是一個'code only'的答案。 – 2014-10-09 15:40:09

+1

@EngineerDollery裏面有一句英文句子。希望你不要相信英語句子是代碼,並且不會遇到某種你無法讀懂任何事情的第一行的綜合徵。除了這兩種情況之外,將來你應該更加小心你的旗幟。 – 2014-10-09 15:47:52

+0

@ R.MartinhoFernandes - 我沒有舉報質量評審;它只是出現在要審查的事情列表中。我將答案標記爲確定,但認爲留下一個關於標記這一事實的好評可能有助於海報像上面的答案一樣更加冗長。另外,在技術上,這不是一個句子 - 這是一個隨機的單詞集合,當以這種方式使用時不能稱爲一個句子 - 我的意思是,你讀過嗎?這對我來說沒有任何意義 - 儘管這不是我原來的觀點。 – 2014-10-09 15:52:12