I want to read a file called maze.txt which contains 0s and 1s (indicated blocked or not), and store every element in the file into 2 dimensionals array called maze[17][17].
maze.txt be like :
11111111111111111
10000000000101001
10100111111001101
10101100001010101
10111010100000001
10000011011111001
11111000010001001
10110010000100101
10110100101110111
10000111000100001
10110011000100101
10110010000011101
10111001111110101
10110010000010001
10010111110101111
10010000000000001
11111111111111111
What I've searched the closest answer is using getline()
plus istringstream()
(refer to : Read from file in c till end of line?)
But above solution only applies when I put a whitespace between each of them, like :
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1
1 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1
1 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 1
1 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 1 0 1 1 1 1 1 0 0 1
1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 1
1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 0 1
1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 1
1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1
1 0 1 1 0 0 1 1 0 0 0 1 0 0 1 0 1
1 0 1 1 0 0 1 0 0 0 0 0 1 1 1 0 1
1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1
1 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 1
1 0 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
My code:
void read_maze(int map[17][17]) {
ifstream read_file("D:/maze.txt", ios::in);
if (read_file.good()){
string str;
int i = 0;
while (getline(read_file, str) {
int j = 0;
istringstream ss(str);
int num;
while (ss >> num)
{
map[i][j] = num;
j ;
}
i ;
}
}
for (int i = 0; i < 17; i )
{
for (int j = 0; j < 17; j )
{
cout << map[i][j];
}
cout << endl;
}
read_file.close();
}
output is like original maze.txt
So, what should I do to store each of the element in maze.txt into an array without modifying the content of it?
I believe there might be some easier solutions to it, but since I'm a newbie to C , I can't find any of similar situations like me.
Hope someone can provide detailed code based on above code. Thanks a lot!
CodePudding user response:
You can do it like this :
#include <array>
#include <iostream>
#include <string>
#include <sstream>
std::istringstream file{
"11111111111111111\n"
"10000000000101001\n"
"10100111111001101\n"
"10101100001010101\n"
"10111010100000001\n"
"10000011011111001\n"
"11111000010001001\n"
"10110010000100101\n"
"10110100101110111\n"
"10000111000100001\n"
"10110011000100101\n"
"10110010000011101\n"
"10111001111110101\n"
"10110010000010001\n"
"10010111110101111\n"
"10010000000000001\n"
"11111111111111111\n"
};
auto load(std::istream& is)
{
// use std::array, you can actually return that from functions
// and avoids the pain of having to work with double pointers
// and manual memory managment.
std::array<std::array<char, 17>, 17> map{};
// loop over all rows in the map
for (auto& row : map)
{
// loop over all the values in a row
for (auto& value : row)
{
// read one value from the file
is >> value;
}
// newlines will be skipped.
}
// and return your map (2d array)
return map;
}
int main()
{
// file is a stringstream now but
// is easily replaced by a filestream
// (stringstream just makes testing more easy)
auto map = load(file);
// just another range based for loop
// to display the map we read from file.
for (const auto& row : map)
{
for (const auto& value : row)
{
std::cout << value;
}
std::cout << "\n";
}
}
CodePudding user response:
Your code would work with a slight modification. Like this:
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
void read_maze(int map[17][17]) {
ifstream read_file("maze.txt", ios::in);
if (read_file.good()){
string str;
int i = 0;
while (getline(read_file, str)) {
// read line and process each digit
for (int j=0; j < str.size(); j ) {
map[i][j] = str[j] - '0';
}
i ;
}
}
for (int i = 0; i < 17; i )
{
for (int j = 0; j < 17; j )
{
cout << map[i][j] << " ";
}
cout << endl;
}
read_file.close();
}
int main() {
int map[17][17] = {};
read_maze(map);
}