2017-04-04 73 views
0

我正在研究一個代碼,該代碼讀取包含跑道「course」的文件,並且需要確定首先課程的高度和寬度。樣品過程看起來像這樣:動態分配的數組在輸出時丟失ifstream數據

xxxxXxxxxXxxxxXxxxxXxxxxXxxxxX 
xxxxxx  xxxxx  xxx xx 
xxxxx  xxx  xx x 
xx  xx  x  x  x 
X  xx    x x x 
x  xx     x x 
x  xxxxxxxxxxxxxx  x x 
x  xxxxxxxxxxxxxxxxxxxxx x 
xFFFF x xxxxxxxxxxxxxx  x 
XFFFF x xxxxxxxx   x 
x  x  1    x 
xxxxxxx  2  xxx x 
xxxxxx  3   x  x 
x       x 
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 

現在因爲陣列需要在編譯時間常數的值,並且我不能提供的是,我試圖陣列動態分配給存儲器一次的高度和寬度值被檢索。總之,我的代碼看起來就像這樣:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <iostream> 
#include <vector> 

using namespace std; 

struct Level { 
    int HEIGHT; 
    int WIDTH; 
}; 

vector<Level> getRowCol(istream& fin) { 

    vector<Level> level; 

    fin.seekg(0, fin.end); 
    int fileSize = fin.tellg(); 
    fin.seekg(0, fin.beg); 

    string s; 
    if (getline(fin, s)) { 
     Level l; 

     l.WIDTH = s.size(); 
     l.HEIGHT = fileSize/(l.WIDTH + 1); 

     level.push_back(l); 
    } 

    return level; 
} 

void readCourse(int& cols, int& rows, istream& fin) { 

    char** level = new char*[rows]; 
    for (int i = 0; i < cols; i++) { 
     level[i] = new char[cols]; 
    } 

    for (int i = 0; i < rows; i++) { 
     for (int j = 0; j < cols; j++) { 
      level[i][j] = 0; 
     } 
    } 

    for (int i = 0; i < rows; i++) { 
     for (int j = 0; j < cols; j++) { 
      fin.get(level[i][j]); 
     } 
    } 

    for (int i = 0; i < rows; i++) { 
     for (int j = 0; j < cols; j++) { 
      cout << level[i][j]; 
     } 
    } 
} 


int main(int argc, char** argv) { 
    vector<Level> course; 
    ifstream fin(argv[1]); 

    course = getRowCol(fin); 

    cout << course[0].WIDTH << " columns" << endl; 
    cout << course[0].HEIGHT << " rows" << endl; 

    readCourse(course[0].WIDTH, course[0].HEIGHT, fin); 

    return 0; 
} 

傳遞時通過命令行的文件中的這段代碼的輸出如下:

31 columns 
14 rows 
xxxxxx  xxxxx  xxx xx 
xxxxx  xxx  xx x 
xx  xx  x  x  x 
X  xx    x x x 
x  xx     x x 
x  xxxxxxxxxxxxxx  x x 
x  xxxxxxxxxxxxxxxxxxxxx x 
xFFFF x xxxxxxxxxxxxxx  x 
XFFFF x xxxxxxxx   x 
x  x  1    x 
xxxxxxx  2  xxx x 
xxxxxx  3   x  x 
x       x 
Xxxxxxxxxxxxxxxxxx 

有現在似乎是空白。如果在編譯時間之前聲明const int值,則不會出現這些間隔。然而,我不能想到另一種方法來使用未知值構建數組,直到腳本運行時沒有使用動態分配。

有沒有其他的或更好的方法來實現這一目標?

+1

爲什麼不堅持使用'std :: vector'而不是在'readCourse'函數中引入巨大的內存泄漏?一個'std :: vector >級別(行,std :: vector (cols));'本來是使用vector的方式。 – PaulMcKenzie

+0

@PaulMcKenzie嗯。我不得不進一步看看。在第一次測試中,根據您的推薦更改動態分配會產生相同的結果。我對媒介不太熟悉,你能否進一步闡述糾正? –

+0

我發佈的代碼糾正了您原來的一個大錯誤,因爲沒有內存泄漏。您已經在'getRowCol'函數中使用'std :: vector',並且所有的聲明都聲明瞭一個矢量矢量,因此本質上是一個動態二維數組。 – PaulMcKenzie

回答

0

您的第一個業務訂單是致電getRowCol(),它以相當迂迴的方式嘗試事先確定文件中地圖的大小。它通過確定文件的大小,然後倒回到文件的開頭,讀取第一行,獲取其長度,並從中計算行數來完成此操作。

但是,如果您非常小心地注意,您會意識到當getRowCol()返回時,會在之後讀取文件的第一行。但是,後面的代碼假定它從文件的開頭讀取,並讀取整個地圖。當然,這不會再發生,因爲文件中的第一行已被讀取。

這解釋了您的問題的第一部分,缺失的一行和缺口。

至於你的問題的第二部分:所有這些複雜的邏輯是絕對完全不必要的。

你的代碼表明你對基本的知識和對矢量如何工作的理解。

那麼,爲什麼首先需要這種複雜的邏輯呢?

只需打開文件,並將文件的每一行讀入一個矢量,push_back()讀取每行之後,直到達到文件末尾。

當所有事情都說完之後,矢量的大小就是地圖的高度。因爲該向量包含文件中每一行的一個值。通過查看每一行的大小,你就知道地圖有多寬。

就是這樣。也許有十幾行代碼,但不超過這一行。比你在這裏展示的更簡單,更容易理解。您現有的邏輯(獲取文件大小,獲取第一行的大小,然後將其彼此分開)非常脆弱。如果出於某種原因,文件中的行長度不一(可能其中一些尾部有空格),則您的計算結果將完全關閉。有了這個,更簡單的方法,處理這種錯誤情況變得更加容易,並且仍然會產生一些有意義的結果。

+0

我對我的代碼進行了邏輯更改。但是,當我嘗試輸出矢量時,它全部在一行上。我應該將它們逐行添加爲字符串還是作爲char向量? –

+0

我不確定你如何獲得矢量元素的長度。 '.size'給我地圖的「高度」,但不是寬度。沒有'myvector [0] .size()'方法。 –

+0

當然有。使用'std :: vector myvector','myvector [0]'將是一個'std :: string',它具有一個功能完善的'size()'方法。 –