如何将文件中的字符放入二维向量中?
How to put characters from file into two-dimensional vector?
我一直在尝试从外部文件中读入字符,并将其放入类型为 char
的二维向量中。这些元素必须能够与某些值进行比较,以便在“MazeSample.txt
”中给出的迷宫中导航。
虽然我无法将字符放入向量中,但我能够使用 get
和 cout
函数读取和输出字符。
以下代码试图以正确的格式读取向量,但最终出现错误:
//MazeSample.txt
SWWOW
OOOOW
WWWOW
WEOOW
//source.cpp
vector<vector<char>> maze;
ifstream mazeFile;
char token;
mazeFile.open("MazeSample.txt");
while (!mazeFile.eof()) {
mazeFile.get(token); //reads a single character, goes to next char after loop
for (int row = 0; row < maze.size(); row++) {
for (int column = 0; column < maze.at(row).size(); row++) {
maze.push_back(token);
}
}
//cout << token;
}
mazeFile.close();
对于“MazeSample.txt
”中提供的迷宫,我希望 maze
向量逐行读取每个字符,模仿迷宫示例的格式。
在上面的代码中,在 maze.push_back(token)
处出现错误:
"no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back..."匹配参数列表"
"argument types are: (char)"
"object type is: std::vector>, std::allocator>>>"
您的问题的原因是您试图将一个字符放入 std::vector 的 std 向量中。所以你输入错误的类型。
maze.at(row).push_back(token);
会这样做,但是没有行存在。您还需要 push_back 和空行,然后才能向其写入数据。
那是你的语法错误。
然后,您的代码可以通过使用 C++ 算法大大缩短。参见:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
// This is a proxy to read a complete line with the extractor operator
struct CompleteLineAsVectorOfChar {
// Overloaded Extractor Operator
friend std::istream& operator>>(std::istream& is, CompleteLineAsVectorOfChar& cl) {
std::string s{}; cl.completeLine.clear(); std::getline(is, s);
std::copy(s.begin(), s.end(), std::back_inserter(cl.completeLine));
return is; }
operator std::vector<char>() const { return completeLine; } // Type cast operator for expected value
std::vector<char> completeLine{};
};
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::vector<char>> maze { std::istream_iterator<CompleteLineAsVectorOfChar>(testDataFile), std::istream_iterator<CompleteLineAsVectorOfChar>() };
// Debug output: Copy all data to std::cout
std::for_each(maze.begin(), maze.end(), [](const std::vector<char> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<char>(std::cout, " ")); std::cout << '\n'; });
return 0;
}
但这还没有结束。 std::vector<char>
与字符串相比没有任何优势。您可以工作几乎具有与 std::vector<char>
相同的所有功能。这是设计上的改进。代码看起来更像这样:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };
// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
这是迄今为止更简单的解决方案。它也将满足您的需求。
请注意:我使用 istringstream 读取数据,因为我在 SO 上没有文件。但这与使用任何其他流(如 ifstream)的原因相同。
编辑
第一种方案读取源码直接放到一个std::vector<std::vector<char>>
:
第二种解决方案将所有内容都放在 std::vector<std::vector<std::string>>
中,这是最有效的解决方案。另外 std::string
几乎是 std::vector<std::vector<char>>
.
OP 要求第三个解决方案,我们使用第二个解决方案,然后将 std::vector<std::vector<std::string>>
复制到 std::vector<std::vector<char>>
。
请看下面
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };
// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
// Edit: Copy into a std::vector<std::vector<char> -------------------------------------------------------
std::cout << "\n\n\nSolution 3:\n\n";
// Define the new variable with number of lines from the first maze
std::vector<std::vector<char>> mazeChar(maze.size());
// Copy the data from the original maze
std::transform(
maze.begin(), // Source
maze.end(),
mazeChar.begin(), // Destination
[](const std::string & s) {
std::vector<char>vc; // Copy columns
std::copy(s.begin(), s.end(), std::back_inserter(vc));
return vc;
}
);
// Debug Output
std::for_each(
mazeChar.begin(),
mazeChar.end(),
[](const std::vector<char> & vc) {
std::copy(vc.begin(), vc.end(), std::ostream_iterator<char>(std::cout));
std::cout << '\n';
}
);
return 0;
}
希望这对您有所帮助。 . .
您正在插入 char
到 vector<vector<char>>
。您应该创建一个 vector<char>
,将 char
类型的值插入其中,然后将 vector<char>
插入 vector<vector<char>> maze;
。这是您的程序的更正版本。可以写得很简单,但是为了您的理解,我已经在您的程序之上做了更正。
vector<vector<char>> maze;
ifstream mazeFile;
string token;
mazeFile.open("MazeSample.txt");
while (!mazeFile.eof()) {
std::getline(mazeFile, token); //reads an entire line
//Copy characters in entire row to vector of char
vector<char> vecRow;
vecRow.assign(token.begin(), token.end());
//Push entire row of characters in a vector
maze.push_back(vecRow);
}
mazeFile.close();
我一直在尝试从外部文件中读入字符,并将其放入类型为 char
的二维向量中。这些元素必须能够与某些值进行比较,以便在“MazeSample.txt
”中给出的迷宫中导航。
虽然我无法将字符放入向量中,但我能够使用 get
和 cout
函数读取和输出字符。
以下代码试图以正确的格式读取向量,但最终出现错误:
//MazeSample.txt
SWWOW
OOOOW
WWWOW
WEOOW
//source.cpp
vector<vector<char>> maze;
ifstream mazeFile;
char token;
mazeFile.open("MazeSample.txt");
while (!mazeFile.eof()) {
mazeFile.get(token); //reads a single character, goes to next char after loop
for (int row = 0; row < maze.size(); row++) {
for (int column = 0; column < maze.at(row).size(); row++) {
maze.push_back(token);
}
}
//cout << token;
}
mazeFile.close();
对于“MazeSample.txt
”中提供的迷宫,我希望 maze
向量逐行读取每个字符,模仿迷宫示例的格式。
在上面的代码中,在 maze.push_back(token)
处出现错误:
"no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back..."匹配参数列表"
"argument types are: (char)"
"object type is: std::vector>, std::allocator>>>"
您的问题的原因是您试图将一个字符放入 std::vector 的 std 向量中。所以你输入错误的类型。
maze.at(row).push_back(token);
会这样做,但是没有行存在。您还需要 push_back 和空行,然后才能向其写入数据。
那是你的语法错误。
然后,您的代码可以通过使用 C++ 算法大大缩短。参见:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
// This is a proxy to read a complete line with the extractor operator
struct CompleteLineAsVectorOfChar {
// Overloaded Extractor Operator
friend std::istream& operator>>(std::istream& is, CompleteLineAsVectorOfChar& cl) {
std::string s{}; cl.completeLine.clear(); std::getline(is, s);
std::copy(s.begin(), s.end(), std::back_inserter(cl.completeLine));
return is; }
operator std::vector<char>() const { return completeLine; } // Type cast operator for expected value
std::vector<char> completeLine{};
};
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::vector<char>> maze { std::istream_iterator<CompleteLineAsVectorOfChar>(testDataFile), std::istream_iterator<CompleteLineAsVectorOfChar>() };
// Debug output: Copy all data to std::cout
std::for_each(maze.begin(), maze.end(), [](const std::vector<char> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<char>(std::cout, " ")); std::cout << '\n'; });
return 0;
}
但这还没有结束。 std::vector<char>
与字符串相比没有任何优势。您可以工作几乎具有与 std::vector<char>
相同的所有功能。这是设计上的改进。代码看起来更像这样:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };
// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
这是迄今为止更简单的解决方案。它也将满足您的需求。
请注意:我使用 istringstream 读取数据,因为我在 SO 上没有文件。但这与使用任何其他流(如 ifstream)的原因相同。
编辑
第一种方案读取源码直接放到一个std::vector<std::vector<char>>
:
第二种解决方案将所有内容都放在 std::vector<std::vector<std::string>>
中,这是最有效的解决方案。另外 std::string
几乎是 std::vector<std::vector<char>>
.
OP 要求第三个解决方案,我们使用第二个解决方案,然后将 std::vector<std::vector<std::string>>
复制到 std::vector<std::vector<char>>
。
请看下面
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");
int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };
// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
// Edit: Copy into a std::vector<std::vector<char> -------------------------------------------------------
std::cout << "\n\n\nSolution 3:\n\n";
// Define the new variable with number of lines from the first maze
std::vector<std::vector<char>> mazeChar(maze.size());
// Copy the data from the original maze
std::transform(
maze.begin(), // Source
maze.end(),
mazeChar.begin(), // Destination
[](const std::string & s) {
std::vector<char>vc; // Copy columns
std::copy(s.begin(), s.end(), std::back_inserter(vc));
return vc;
}
);
// Debug Output
std::for_each(
mazeChar.begin(),
mazeChar.end(),
[](const std::vector<char> & vc) {
std::copy(vc.begin(), vc.end(), std::ostream_iterator<char>(std::cout));
std::cout << '\n';
}
);
return 0;
}
希望这对您有所帮助。 . .
您正在插入 char
到 vector<vector<char>>
。您应该创建一个 vector<char>
,将 char
类型的值插入其中,然后将 vector<char>
插入 vector<vector<char>> maze;
。这是您的程序的更正版本。可以写得很简单,但是为了您的理解,我已经在您的程序之上做了更正。
vector<vector<char>> maze;
ifstream mazeFile;
string token;
mazeFile.open("MazeSample.txt");
while (!mazeFile.eof()) {
std::getline(mazeFile, token); //reads an entire line
//Copy characters in entire row to vector of char
vector<char> vecRow;
vecRow.assign(token.begin(), token.end());
//Push entire row of characters in a vector
maze.push_back(vecRow);
}
mazeFile.close();