2016-08-25 67 views
0

我想讀取.txt文件。如何創建不同大小字符串的動態二維數組

.txt文件將包含N行和M列。

txt文件中的每個單詞將具有不同的長度。

樣品txt文件:txt文件的

Suppose N = 4 rows 

Suppose M = 5 cols 

內容:

aa bbb cc dddddddd eeee 

aa bbbbbbbbbbbb cc ddddddddddd eeee 

aaaaaaaaaa bb cc d e 

a b c d eeee 

我要做的:

我必須將這些字符串存儲到字符串的二維陣列,使得它看起來是這樣的:

arr[4][5] = 

[aa    bbb    cc  dddddddd  eeee] 

[aa    bbbbbbbbbbbb  cc  ddddddddddd  eeee] 

[aaaaaaaaaa  bb    cc  d    e ] 

[a    b    c  d    eeee] 

我知道如何創建整數的動態二維數組和它的做工精細:

int** arr; 
int* temp; 

arr = (int**)malloc(row*sizeof(int*)); 
temp = (int*)malloc(row * col * sizeof(int)); 
for (int i = 0; i < row; i++) 
{ 
    arr[i] = temp + (i * col); 
} 
int count = 0; 
//setting values in 2-D array 
for (int i = 0; i < row; i++) 
{ 
    for (int j = 0; j < col; j++) 
    { 
     arr[i][j] = count++; 
    } 
} 

但是,當我試圖爲字符串做同樣的事情時,它會崩潰。

string** arr; 
string* temp; 

arr = (string**)malloc(row*sizeof(string*)); 
temp = (string*)malloc(row * col * sizeof(string)); 
for (int i = 0; i < row; i++) 
{ 
    arr[i] = temp + (i * col); 
} 

//setting values in 2-D array 
for (int i = 0; i < row; i++) 
{ 
    for (int j = 0; j < col; j++) 
    { 
     arr[i][j].append("hello"); // CRASH here !! 
    } 
} 

如何將每個單詞存儲在數組中?

這是我寫:

#include "stdafx.h" 
#include <cstdlib> 
#include <iostream> 
#include <vector> 
#include <map> 
#include <fstream> 
#include <string> 
#include <algorithm> 
#include <assert.h>  /* assert */ 
using namespace std; 

vector<string> readFile(const string file, int& row, int& col) 
{ 
    vector<string> buffer; 

    ifstream read(file); 
    string line; 
    char * writable = NULL; 

    if (read.is_open()) 
    { 
     int temp_counter = 0; 
     while (!read.eof()) 
     { 
      std::getline(read, line); 
      writable = new char[line.size() + 1]; 
      std::copy(line.begin(), line.end(), writable); 
      writable[line.size()] = '\0'; // don't forget the terminating 0 
      if (temp_counter == 0)// 
      { 
       row = std::stoi(line); 
       ++temp_counter; 
      } 
      else if (temp_counter == 1) 
      { 
       col = std::stoi(line); 
       ++temp_counter; 
      } 
      else 
      { 
       buffer.push_back(line); 
      }  
     } 
    } 
    // don't forget to free the string after finished using it 
    delete[] writable; 
    return buffer; 
} 

void create2DDynamicArray(std::vector<string>&v, int row, int col) 
{ 
    string** arr; 
    string* temp; 

    arr = (string**)malloc(row*sizeof(string*)); 
    temp = (string*)malloc(row * col * sizeof(string)); 
    for (int i = 0; i < row; i++) 
    { 
     arr[i] = temp + (i * col); 
    } 


    //setting values in 2-D array 
    for (int i = 0; i < row; i++) 
    { 
     for (int j = 0; j < col; j++) 
     { 
      arr[i][j].append("hello"); 
     } 
    } 
} 
int main() 
{ 
    vector<string> myvector; 
    int row=0; 
    int col=0; 

    myvector = readFile("D:\\input.txt", row, col); 
    create2DDynamicArray(myvector, row, col); 

    getchar(); 
    return 0; 
} 

txt文件的樣子:

AA BBB CC DDDDDDDD EEEE

AA bbbbbbbbbbbb CC ddddddddddd eeee

AAAAAAAAAA BB CC dË

A B C d EEEE

+0

你改變INT爲char。您爲字符串分配空間,而不是爲int分配空間。 – Mirakurun

+0

添加爲每個字符串的空字符分配一個額外的條目。 –

+2

爲什麼不選擇* C和C++之一?如果你打算使用C,他們會說[你不應該在C]中拋出'malloc()'的結果(http://stackoverflow.com/questions/605845/do-i-cast-the-result-的-的malloc)。如果你打算使用C++,爲什麼不使用'new []'而不是'malloc()'? – MikeCAT

回答

4

不要用C使用malloc ++。它不會運行字符串的構造函數,因此不會爲存儲在其中的動態字符數組分配空間。改爲使用new[]運算符或智能指針。

string **arr; 
arr = new string*[height]; 
for (int i = 0; i < height; i++) 
    arr[i] = new string[width]; 

一個C++ string只是一種包裝物圍繞一個動態char陣列,其必須被初始化(它應該有分配給它的存儲器)。通過使用malloc,您不會調用構造函數,從而導致訪問未分配的內存區域。

0

如果你真的想用二維數組與malloc我的建議分配的內存是轉向從string **string ***類型,如:

ifstream f(your_file_name); 

    string*** arr; 

    arr = (string***)malloc(row*sizeof(string**)); 

    for (int i = 0; i < row; i++) 
    { 
     arr[i] = (string**)malloc(col * sizeof(string*)); 
    } 

    //setting values in 2-D array 
    for (int i = 0; i < row; i++) 
    { 
     for (int j = 0; j < col; j++) 
     { 
      arr[i][j] = new string(); 
      f >> *arr[i][j]; // or arr[i][j] -> append("hello"); 
     } 
    } 

但如果真的C++項目考慮使用vector<vector<string>>甚至使用new而不是malloc,如:

ifstream f("tmp.txt"); 

    string** arr; 

    arr = new string*[row]; 

    for (int i = 0; i < row; i++) 
    { 
     arr[i] = new string[col]; 
    } 

    //reading 2-D array from file 
    for (int i = 0; i < row; i++) 
    { 
     for (int j = 0; j < col; j++) 
     { 
      f >> arr[i][j]; 
     } 
    } 
    // show file content 
    for (int i = 0; i < row; i++) 
    { 
     for (int j = 0; j < col; j++) 
     { 
      cout << arr[i][j] << " "; 
     } 
     cout << endl; 
    } 
2

我建議,以避免分散和使用一個真正的二維數組。

在C中,因爲C99可以用VLA的(可變長度數組):

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int rows = 4, cols = 5; 
    char *(*arr)[cols]; 
    int i, j; 

    arr = malloc(sizeof(*arr) * rows); 
    for (i = 0; i < rows; i++) { 
     for (j = 0; j < cols; j++) { 
      arr[i][j] = "hello"; /* For read only, to be writable use strdup */ 
     } 
    } 
    for (i = 0; i < rows; i++) { 
     for (j = 0; j < cols; j++) { 
      printf("%s\t", arr[i][j]); 
     } 
     printf("\n"); 
    } 
    free(arr); 
    return 0; 
} 

輸出:在C和這不會

hello hello hello hello hello 
hello hello hello hello hello 
hello hello hello hello hello 
hello hello hello hello hello 

arr[i][j].append("hello"); // CRASH here !! 

有不是方法編譯,爲什麼混合使用C和C++?挑一個。

+1

即使C99不可用,只要行和列是編譯時常量,該方法即使在古代C編譯器或C++編譯器中也可以工作。我個人比較喜歡使用'arr = malloc(sizeof(char * [rows] [cols]));'這樣可以使意圖更清晰,它是自編檔案的代碼。 – Lundin

+0

@Lundin你確定嗎? 'gcc -std = c89':'ISO C90禁止變長陣列'arr'' –

+0

當cols被定義爲enum {cols = 5};'或'#define cols 5'時,警告消失但仍然使用'int cols = 5;'甚至使用'const':相關問題:http://stackoverflow.com/q/436300/1606345 –

1

不要使用malloc,避免new/new[]和使用RAII容器:

std::vector<std::vector<std::string>> readFile(const std::string& filename) 
{ 
    std::ifstream file(filename); 
    int row; 
    int col; 
    file >> row >> col; 

    std::vector<std::vector<std::string>> words(row, std::vector<std::string>(col)); 

    for (auto& rows : words) { 
     for (auto& word : rows) { 
      file >> word; 
     } 
    } 
    return words; 
} 
1

enter image description here

載體也是動態數組,但是從隱藏在跟蹤指針的所有工作用戶。

如果你決定使用向量,而不是再編碼的2D動態數組是因爲這很容易:

#include <iostream> 
#include <vector> 
#include <string> 
#include <fstream>  
using namespace std; 


int main() { 

    cout<<"\nDynamic 2D Array.\n\n"; 

    // create string vector 
    vector<string> vArray; 

    // create one line string 
    string line; 

    // open file for reading 
    ifstream fileToRead("d2d.txt"); 
    while (getline(fileToRead, line)){ 

     // fuse (store) line from file in vector 
     vArray.push_back(line); 
    } 
    fileToRead.close(); 

    // display results 
    for (int i=0; i< vArray.size();i++){ 
     cout<<" [ "<< vArray[i] <<" ] \n"; 
    } 

cout<<"\nPress ANY key to close.\n\n"; 
cin.ignore(); cin.get(); 
return 0; 
} 
相關問題