2017-04-17 61 views
0

我有我不能改變的輸入文件,具有略微不同線從輸入文件C++讀取與istream的操作符重載

Supercar HTT Technologies 10 2 
Motorcycle Honda 40 1 
... 

我爲了中的值讀入我的數據重載>>操作符結構,主要內容如下:

class Vehicles{ 
private: 
string type; //type of vehicle, i.e. car/motorcycle 
string manufacturer; 
string manufacturer2ndPart //not a good idea, but this is what I'm using 
          //to get the second part of the manufacturer ("Technologies") 
int milesPerGallon; 
int numPrevOwn //number of previous owners 
public: 
... 

friend istream &operator >> (istream &is, Vehicles &Vec){ 
is >> Vec.type >> Vec.manufacturer >> Vec.milesPerGallon >> Vec.numPrevOwn; 
return is; 
    } 
}; 

這對第一線工作正常,但打破了輸入文件的第二行,因爲它試圖「40」讀成manufacturer2,而不是milesPerGallon。解決這個問題最好的辦法是什麼?我想避免手動讀取所有內容,因爲這會破壞操作員重載的目的。

+0

剛剛編輯了一下這篇文章。第一行讀入並輸出完全正常。第二行讀入字符串「manufacturer2ndPart」中的「40」,而不是讀入int milesPerGallon,從而使numPrevOwn成爲內存中的任何值。 –

+1

這些值是如何分開的? – Jonas

+2

您必須知道輸入文件的格式。例如,你怎麼知道它沒有與製造商「技術」一起輸入「Supercar HTT」?應該有一條規則,例如「列至少分隔2個空格」或「列總是14個字符寬」 – nwp

回答

1

你的基本問題是流的>>所有的停止當他們遇到空白,並且你的輸入文件包含空格作爲數據,而不是作爲忽略的東西。因此,您需要根據線路需要不同數量的字符串的問題。

一般來說,你最好一次讀一整行到一個字符串(例如使用std::getline())。然後在試圖實際提取它們之前,檢查字符串以計算它實際包含的字段數。換句話說,不要使用流操作符來讀取文件(或寫入文件)。

它可能還會稍微改變文件格式,所以當字符串字段的開始時它變得很明顯。例如,像

"Supercar" "HTT Technologies" 10  2 
"Motorcycle" "Honda" 40  1 

你仍然需要一次讀取一條線,但使用"分隔字符串可以更容易地識別開始和每個每個字符串,並處理含有它們的格式空格(除了換行符)。如果您需要在字符串中包含"字符,請指定它將在前面加上\,並相應地解析輸入。

顯然,任何讀取或寫入此類文件的代碼都需要遵守相同的協議。閱讀代碼需要處理錯誤(例如,不符合協議的文件)。

+0

似乎是一個好主意,使用getline,我會結合這與stringstream,是嗎?我只是有點困惑,我怎麼會真正確定有多少「字段「中存在字符串,因爲它看起來像以前一樣的讀取過程。 不幸的是,我不能改變文件格式,但我希望我能:P –

+2

你可以使用'stringstream'。如果您無法更改文件格式,則需要直接檢查每一行(例如,循環中的每個字符),並計算出在整數值之前可能有多少個字符串數據 - 大概在最後。你需要處理像「SuperCar6 Company Fumbler#2 10 20」這樣的輸入 - 這可以通過向後反向處理字符串,計數數字和空格來處理,直到達到最後一個字符串數據的末尾。 – Peter