我有一个C ++编程任务,我必须从文本文件中读取并将输入存储在2d数组中。但是文本文件仅包含矩阵,不存储有关行和列的信息。我的程序将通过几个输入进行测试,因此2d数组不应具有固定的大小。但是,此矩阵不能保证是平方的。那么,当用多个输入文件进行测试时,如何将这个矩阵存储在具有动态尺寸的二维数组中?
答案 0 :(得分:0)
在C程序中,我们经常可以找到具有一个或多个维的纯数组。这些普通数组的缺点是,维数(元素数)必须是编译时间常数。它需要在编译时预先确定,并且不能增长。
这不是很有帮助,通常会导致诸如“越界”之类的错误。并且人们为安全起见保留了一些缓冲。因此,您经常会在旧式代码数组中找到以下内容:
int i = 3;
char buf[100]; /* Make array big enough to hold int string in any case */
sprintf(buf,"%d",i);
这不是很好。但是幸运的是,在C ++中,我们的STL容器可以满足我们的所有要求。一个示例是std :: vector。它可以动态初始化并可以增长。索引运算符的工作方式类似于普通的旧数组。很好
但是下一个问题是,如何添加更多尺寸?答案是使用向量的向量。对于每个维度,我们将在另一个向量内添加一个新向量。对于二维矩阵,这意味着:
std::vector<int> columns;
std::vector<std::vector<int>> matrix;
这可能有点难以理解。 “ Typedef”或“ using”将使我们更容易阅读:
using ElementsInColumns = std::vector<int>; // This is one row with columns
using Rows = std::vector<ElementsInColumns>; // This is the matrix. Consisting of Rows (with columns)
constexpr size_t NumberOfRows = 4;
constexpr size_t NumberOfColumns = 7;
Rows matrix(NumberOfRows, ElementsInColumns(NumberOfColumns));
matrix[1][2] = 5;
现在回到您的问题
如何在不知道尺寸的情况下以2d数组输入输入
我们将使用上述机制。向量的向量。两个向量都将根据需要增长。而且,如果我们想从具有行和列的文件中读取字符串(无论数字是多少),都可以使用此方法来实现。
查看可能的输入文件“ input.txt”
Col_1 Col_2 Col_3 Col_4 Col_5 Col_6
Col_1 Col_2 Col_3
Col_1 Col_2 Col_3 Col_4 Col_5 Col_6 Col_7
Col_1 Col_2 Col_3 Col_4 Col_5
如果我们在输入文件中将所有内容视为字符串,则将使用std::vector<std::vector<std::string>>
读取此类文件并显示一些调试输出的一种可能的实现方式是:
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <sstream>
using ElementsInColumns = std::vector<std::string>;
using Rows = std::vector<ElementsInColumns>;
struct Line // ! This is a proxy for the input_iterator !
{ // Input function. Read on line of text file and split it in columns
friend std::istream& operator>>(std::istream& is, Line& line) {
std::string wholeLine; std::getline(is, wholeLine); std::istringstream iss{ wholeLine }; line.elementsInColumns.clear();
std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(line.elementsInColumns));
return is;
}
operator ElementsInColumns() const { return elementsInColumns; } // cast to needed result
ElementsInColumns elementsInColumns{}; // Local storage for all words in line
};
int main()
{
std::ifstream inFileStream{ "r:\\input.txt" }; // Open input file. Will be closed by destructor
if (!inFileStream) { // ! operator is overloaded
std::cerr << "Could not open input file\n";
}
else {
// 1. Read complete input file into memory and organize it in columns by rows
Rows rows{ std::istream_iterator<Line>(inFileStream), std::istream_iterator<Line>() };
// 2. Calculate number of columns for a rectangular matrix. You could also use "min_element"
const size_t numberOfColumns{std::max_element(rows.begin(), rows.end(), [](const ElementsInColumns & eicLeft, const ElementsInColumns & eicRight) {return eicLeft.size() < eicRight.size(); })->size()};
// 3. Make exact numberOfColumns entries for all rows. Do this, if you want to have a rectangular matrix.. Empty cols will be filled with _____ (or whatever you like)
std::for_each(rows.begin(), rows.end(), [numberOfColumns](ElementsInColumns& eic) {eic.resize(numberOfColumns, "_____"); });
// 4. Debug Output
std::cout << "\nMatrix\n\nRows: " << rows.size() << "\nColumns: " << numberOfColumns << "\n\n";
// Copy matrix to std::cout
std::for_each(rows.begin(), rows.end(), [](ElementsInColumns & eic) {std::copy(eic.begin(), eic.end(), std::ostream_iterator<std::string>(std::cout, " ")); std::cout << '\n'; });
}
return 0;
}
该程序将为上述输入提供以下输出:
Matrix
Rows: 4
Columns: 7
Col_1 Col_2 Col_3 Col_4 Col_5 Col_6 _____
Col_1 Col_2 Col_3 _____ _____ _____ _____
Col_1 Col_2 Col_3 Col_4 Col_5 Col_6 Col_7
Col_1 Col_2 Col_3 Col_4 Col_5 _____ _____
请注意:不需要填充(填充空白单元格)。您可以省略第2步和第3步。您将只需要一个衬纸即可读取整个输入文件。
但是后来人们常常通过索引运算符以矩形方式使用矩阵。为此,所有列都应存在。
我希望这有助于更好地理解。 。