2015-10-06 173 views
0

我有一個類似在這裏發表的問題存儲數據:閱讀並從文本文件C++

C++: Read from text file and separate into variable

不同的是,原來的職位曾在下列格式file.txt的:

  • 名稱int INT INT
  • 名稱int INT INT

我的文件格式如下:

  • FNAME LNAME

  • INT INT INT

  • FNAME LNAME

  • INT INT INT

我想閱讀(第一個和最後一個)名稱並存儲我t分配給一個變量,每個int分配到它自己的變量中(用於將來的計算)。

我試過使用類似於答案的東西,但換行符搞亂了我的變量。

作爲額外的好處,我的文件中有隨機的空白行。

這裏是我到目前爲止的代碼

if (myfile.is_open()) 
{  
    while (getline(myfile, line)) 
    { 
     istringstream iss(line); 

     string fname; 

     string lname; 

     if (line != "") 
     { 
      iss >> fname >> lname >> x >> y >> z >> a >> b >> c; 
      cout << "name: " << fname << endl; 
      //iss >> x >> y >> z >> a >> b >> c; 
      cout << "x: " << x << "y: " << y << endl; 

     } 
     else cout << ""; 
    } 
} 
+0

名稱和整數在不同的行中,但您嘗試從同一行中提取它們。 'iss >>'等只能訪問1行。你需要一些方法來記住你在哪一行,並考慮空行。此外,沒有什麼大不了的,但在檢查空白行之前不要設置字符串流,因爲這樣更有效。 –

回答

0

需要2線,打破了你的變量讀數。

iss >> fname >> lname >> x >> y >> z >> a >> b >> c; //don't know why you have 6 ints when you specified 3, I'll assume 6 is correct 

成爲

issFirstLine >> fname >> lname; 
issSecondLine >> x >> y >> z >> a >> b >> c; 

現在有這樣的多種方式。 2個選項是:您可以嘗試分別讀取2行,如果您有2個非空行,則只能進行打印,或者可以使用某種變量來確定您是在名稱還是在int行上,然後相應地打印,並在成功輸出結束時更改預期類型。

0

您可以使用freopen()來讀取文件。如果希望輸入行之間有多個空白行,就不會有問題。

freopen("test.txt","r",stdin); 
string fname; 
string lname; 
int x, y,z ,a ,b ,c; 
while(cin>>fname){ 
cin>>lname>> x >> y >> z ; 
//your other code 
} 
+0

如果他不想接管這樣的標準輸入會怎麼樣? –

0

類似的東西應該工作。

#include <stdio.h> 

int main(int argc, char** argv) { 
    FILE *fin = fopen("in.txt", "r"); 

    char fname[1024], lname[1024]; 
    int x, y, z; 
    while (fscanf(fin, "%s %s %d %d %d", fname, lname, &x, &y, &z) == 5) { 
     printf("%s %s %d %d %d\n", fname, lname, x, y, z); 
    } 

    return 0; 
} 
+0

這不是C++,因爲它是C – Tas

+0

也不保證輸入是在兩行上,或者所請求的元素數量甚至被讀取。 'fscanf(fin,「%s%s \ n%d%d%d」,fname,lname,&x,&y,&z)== 5'會。 – user4581301

+0

@Tas true,但這種方式你沒有「新行」問題,並且通常fscanf比ifstream更快,我相信(除非你使用某種緩衝)。 – anmaxvl

0

OP是如此之近它傷害。

我打算通過引入功能,以幫助消除空白行提出的簡化:

istream & getNonBlankLine(istream & in, 
          string & line) 
{ 
    while (getline(in, line) && line.length() == 0) 
    { 
     //does nothing. If the loop didn't exit, line was blank 
     // if the loop exited, either we're out of lines or we got a valid line 
     // out of lines case is handled by testing the stream state on return 
    } 
    return in; // lets us chain and also lets us easily test the state of the stream 
} 

然後回手頭的工作:

if (myfile.is_open()) 
{ 
    string nameline; 
    string numberline; 
    while (getNonBlankLine(myfile, nameline) && 
      getNonBlankLine(myfile, numberline)) 
    { // got two non-blank lines and the stream is still good 
     //turn lines into streams 
     stringstream namess(nameline); 
     stringstream numberss(numberline); 

     // parse streams 
     if (namess >> fname >> lname && // read in first and last name or return error 
      numberss >> x >> y >> z) // read in x, y, and z or return error 
     { 
      // do stuff with input 
     } 
     else 
     { //something did not read in correctly. Bad line 
      cerr << "invalid input"<< endl; // notify user and abort 
      return -1; 
     } 
    } 
} 

一個不請自來的變化這會檢查所有輸入的有效性。如果輸入不符合,OP的截斷和所有答案到目前爲止將默默地失敗。第一行必須有兩個名字,第二行必須有三個整數。其他任何事情都應該觸發無效的輸入錯誤信息並提前退出。我說應該是因爲我沒有真正測試過這個。