如何创建不同大小的字符串的动态2D数组

时间:2016-08-25 07:26:04

标签: c++ c c++11

我想读一个.txt文件。

.txt文件将包含N行和M-col。

txt文件中的每个单词都有不同的长度。

示例txt文件:

Suppose N = 4 rows

Suppose M = 5 cols

txt文件的内容:

aa bbb cc dddddddd eeee

aa bbbbbbbbbbbb cc ddddddddddd eeee

aaaaaaaaaa bb cc d e

a b c d eeee

我必须做的事情:

我必须将这些字符串存储到2D字符串数组中,使其看起来像这样:

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文件看起来像:

4

5

aa bbb cc dddddddd eeee

aa bbbbbbbbbbbb cc ddddddddddd eeee

aaaaaaaaa bb cc d e

a b c d eeee

5 个答案:

答案 0 :(得分:4)

不要在C ++中使用malloc。它不运行字符串的构造函数,因此不为存储在其中的动态char数组分配空间。请尝试使用new[]运算符或智能指针。

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

c ++ string只是动态char数组的一种包装,必须初始化(它应该分配内存)。使用malloc,您不会调用构造函数,从而导致访问未分配的内存区域。

答案 1 :(得分: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;
}

输出:

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和C ++?选择其中一个。

答案 2 :(得分: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;
}

答案 3 :(得分: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;
} 

答案 4 :(得分:0)

如果您真的想要使用分配有malloc的内存的2D数组,我的建议是从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;
    }