我想读一个.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
答案 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)
向量也是动态数组,但所有工作都是跟踪隐藏用户的指针。
如果您决定使用向量,那么编码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;
}