2013-11-03 151 views
0

好的。所以我試圖從文件中讀取信息並將其放入一個類中。讓我來解釋:將txt文件讀入字符串

比方說,我有一個txt文件,看起來像這樣

1 2 3 4 
5 6 7 8 

現在讓我們假設我有一個類

class Numbers { 
public: 
    Numbers(int first, int second, int third, int fourth) 
    : first(first), second(second), third(third), fourth(fourth){} 

private: 
    int first; 
    int second; 
    int third; 
    int fourth; 
}; 

現在,我想擁有的每一行文件是Numbers的新實例,並且每行中的數字將用作每個實例的數據成員(希望這是有道理的)。

因此,從上述文件閱讀後,我應該有兩個數字實例。第一個包含(1,2,3,4),第二個包含(5,6,7,8)。我有一個函數可以在讀取文件後將字符串轉換爲int。我在創建Numbers實例時遇到了麻煩。有任何想法嗎?

+0

因爲C++一行讀取文件行你可能得的值存儲在一個數組或向量第一。例如'std :: vector >'可以用來存儲數字,就像它們在文件中一樣,然後使用這些值創建對象 – UnholySheep

+0

我建議您搜索StackOverflow for「 C++]解析文件輸入「來獲得一些從文件中提取數字的例子。 –

回答

0

你不需要任何轉換,因爲basic_istream& operator>>(int&)已經這樣做了你

ifstream f; 
f >> first; 

創建Numbers實例可以爲定義構造簡單

Numbers() : first(0), second(0), third(0), fourth(0) {} 

然後

Numbers number1, number2; 

當你定義一個

friend istream &operator>>(istream &f, Number &n) { 
    f >> n.first >> n.second >> n.third >> n.fourth; 
    return f; 
} 

你可以說

f >> number1 >> number2; 
2

你爲什麼不只是所有的數字加載到這樣的載體?

#include <iterator> 
#include <fstream> 
#include <vector> 
#include <iostream> 

std::vector<int> loadNumbersFromFile(const std::string& name) 
{ 
    std::ifstream is(name.c_str()); 
    if (!is) 
    { 
     std::cout << "File could not be opened!" << std::endl; 
    } 
    std::istream_iterator<int> start(is), end; 
    return std::vector<int>(start, end); 
} 

void main() 
{ 
    std::vector<int> numbers = loadNumbersFromFile("file.txt"); 
} 

無需聲明一個類爲。

+0

請將此標記爲答案。 – Damian

0

正如其他人指出的那樣,int的輸入運算符已經將數字序列轉換爲int。然而,這種轉換也會做一些可能正確或不正確的事情:格式化的輸入操作符會跳過前導空白,而不會區分不同種類的空白。也就是說,如果一行包含的值比預期的少,那麼該流將很高興地從下一行讀取它們!這是否正確的行爲取決於確切的用途。由於該問題明確提到了每行中包含四個值的格式,因此我會假定它是而不是可以確定每行上的值少於4個。

防止輸入操作員自動跳過空白可以使用std::noskipws完成。但是,一旦應用了它,就有必要明確地跳過空格。跳過空格,但沒有換行符可以使用自定義的機械手來完成:

std::istream& skipspace(std::istream& in) { 
    std::istream::sentry cerberos(in); 
    if (in) { 
     std::istreambuf_iterator<char> it(in), end; 
     while (it != end 
       && *it != '\n' 
       && std::isspace(static_cast<unsigned char>(*it))) { 
      ++it; 
     } 
    } 
    return in; 
} 

有了這樣的機械手,它是相當簡單的實現讀取線的值,如果沒有足夠的值失敗:

  1. 關閉自動跳過空格。
  2. 使用std::ws跳過前導空白以消除行上的前一行結尾和可能的前導空白。
  3. 讀取每個值,只跳過對象之間的非換行符。

也就是說,該類Numbers的輸入操作是這樣的:

std::istream& operator>> (std::istream& in, Numbers& numbers) { 
    int first, second, third, fourth; 
    if (in >> std::noskipws 
     >> std::ws >> first 
     >> skipspace >> second 
     >> skipspace >> third 
     >> skipspace >> fourth) { 
     numbers = Numbers(first, second, third, fourth); 
    } 
    return in; 
}