I'm having troubles doing a loop for a really basic console game that uses ASCII characters. I want to store the txt file (the map) into a 2d array and then I want to output the 2d array on the console.
You can see 2 loops under here, one for inputting the txt file into a 2d array and the other for outputting the 2d array on the screen.
void Level::load_level() {
Level gameLevel;
ifstream inFile;
gameLevel.map;
inFile.open("level1.txt");
if (inFile.fail()) {
perror("level1.txt");
system("PAUSE");
}
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 74; j++) {
inFile >> map[i][j];
}
}
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 74; j++) {
printf("%c", map[i][j]);
}
printf("\n");
}
inFile.close();
}
So, here is what my txt file looks like:
And here is what my console displays:
It seems like the data in the 2d array isn't store correctly, what should I do in order to keep one loop reading data from the file into a 2d array and another loop displaying the 2d array correctly? I don't know if I made that clear.
Thanks and sorry for my lack of skill(I'm a beginner).
Related
I have a text file that has values and I want to put them into a 2D vector.
I can do it with arrays but I don't know how to do it with vectors.
The vector size should be like vector2D[nColumns][nLines] that I don't know in advance. At the most I can have in the text file the number of columns, but not the number of lines.
The number of columns could be different, from one .txt file to another.
.txt example:
189.53 -1.6700 58.550 33.780 58.867
190.13 -3.4700 56.970 42.190 75.546
190.73 -1.3000 62.360 34.640 56.456
191.33 -1.7600 54.770 35.250 65.470
191.93 -8.7500 58.410 33.900 63.505
with arrays I do it like this:
//------ Declares Array for values ------//
const int nCol = countCols; // read from file
float values[nCol][nLin];
// Fill Array with '-1'
for (int c = 0; c < nCol; c++) {
for (int l = 0; l < nLin; l++) {
values[c][l] = -1;
}
}
// reads file to end of *file*, not line
while (!inFile.eof()) {
for (int y = 0; y < nLin; y++) {
for (int i = 0; i < nCol; i++) {
inFile >> values[i][y];
}
i = 0;
}
}
Instead of using
float values[nCol][nLin];
use
std::vector<std::vector<float>> v;
You have to #include<vector> for this.
Now you don't need to worry about size.
Adding elements is as simple as
std::vector<float> f; f.push_back(7.5); v.push_back(f);
Also do not use .eof() on streams, because it doesn't set it until after the end has been reached and so it will attempt to read the end of the file.
while(!inFile.eof())
Should be
while (inFile >> values[i][y]) // returns true as long as it reads in data to values[x][y]
NOTE: Instead of vector, you can also use std::array, which is apparently the best thing after sliced bread.
My suggestion:
const int nCol = countCols; // read from file
std::vector<std::vector<float>> values; // your entire data-set of values
std::vector<float> line(nCol, -1.0); // create one line of nCol size and fill with -1
// reads file to end of *file*, not line
bool done = false;
while (!done)
{
for (int i = 0; !done && i < nCol; i++)
{
done = !(inFile >> line[i]);
}
values.push_back(line);
}
Now your dataset has:
values.size() // number of lines
and can be adressed with array notation also (besides using iterators):
float v = values[i][j];
Note: this code does not take into account the fact that the last line may have less that nCol data values, and so the end of the line vector will contain wrong values at end of file. You may want to add code to clear the end of the line vector when done becomes false, before you push it into values.
I have a 2d vector of chars that is declared by user input. but, how would i return this 2d vector of chars?
I know i need 2 for loops, but how would i, first get the size of how many vectors there are. second, find the size of one of the vectors in the 2d vector.
For example, lets say the user inputs:
.........
.........
....x....
.........
.........
how would i get the height and the width of this 2d vector and print it out?
what i have so far is this:
for (int i = 0; i < data.size(); i ++) {
for (int j = 0; j < data<data.size()>>; j++) {
}
}
Also, the user is allowed to input files that are larger than the one mentioned. Thats why i cant use an already declared variable.
I think a better question would be " how do i get the length of the 2d vector, and the height of one of the vectors to print out the entire thing? "
You mean:
for (int j = 0; j < data[i].size(); j++) {
You can get the height/rows with data.size() and the columns for each row with data[row].size().
for(i = 0; i < vec2d.size(); ++i) {
for(j = 0; j < vec2d[i].size(); ++j) {
// do whatever with vec2d
}
}
Im trying to assign values to a 2d vector, this is the way that i defined the vector, and also its important to say that rows and columns, are ints previously defined
vector < vector <int>> vec(rows , vector <int> (columns,0));
i want to assign to this vector, each char of a pbm file, this file only have '1' and '0', so this is the way im reading it
char i;
FILE* fp;
fp = fopen("file.pbm", "r");
on this way im assigning values to the vector
for (int h=0; h<rows; h++){
for (int j=0; j<columns; j++){
while((i=fgetc(fp))!=EOF){
vec[h][j] = i;
}
}
}
but when i try to print all the vector content, this one, only have '0'
for (int h=0; h<rows; h++){
for (int j=0; j<columns; j++)
cout << vec[h][j];
cout <<endl;
}
fclose(fp);
If anyone could tell me where im failing when i make this assignment, thanks!
vec[h][j] = i;
for (int h=0; h<rows; h++){
for (int j=0; j<columns; j++){
while((i=fgetc(fp))!=EOF){
vec[h][j] = i;
}
}
}
The while loop runs through the entire file without ever incrementing h and j so you are reading the whole file into the first element. And you are doing this (rows*columns) times.
You'll need to redesign your code to read the code in correctly.
I'm trying to read a file of integer values and push each value into a 2D vector. For whatever reason, my resulting vector is full of zeros, rather than the values that I just read out of the file. Why is this and how do I fix it?
void populateVector(string file, vector<vector<int>>& v, int rows, int cols){
ifstream read(file);
int val;
if (!read.is_open()) {
throw runtime_error("Output file is not open.");
} else {
//Populate 2D vector with values from file
while (read >> val) {
cout << val << endl; //Prints each value being processed. Prints proper value.
for (int i = 0; i < rows; i++) {
vector<int> newCol;
v.push_back(newCol);
for (int j = 0; j < cols; j++) {
v.at(i).push_back(val);
}
}
}
}
}
When I print the vector it is populated solely of zeros, even though the read values that are printed to standard output are what I expect (the values from the file).
Your solution would push all the numbers 'cols' times into each row, that is you end up with row * (cols * n) matrix. Look at your loops correctly.
I assume you meant to read each number only once. Then change your loop to something like following (add error checking as necessary)
for (int i = 0; i < rows; i++)
{
std::vector<int> newRow;
for (int j = 0; j < cols; j++)
{
int val;
read >> val;
newRow.push_back(val);
}
v.push_back(newRow);
}
If you want to read one value at a time, you may want to consider a loop like this:
unsigned int column = 0;
std::vector<std::vector<int> > matrix;
std::vector<int> data_row;
while (read >> value)
{
data_row.push_back(value);
++column;
if (column > MAXIMUM_COLUMNS)
{
matrix.push_back(row_data);
data_row.clear();
column = 0;
}
}
The above code builds a row of data, one column at a time. When enough columns are read, the row is then appended to the matrix.
I tried searching through this website for possible answers of why this error is occurring but couldn't find the exact answer.
For this little code, I basically have the program read input from a file. (It reads every single character.) Then store it in a multi-dimensional array (2D) and finally print out the array.
This is my code:
ifstream file;
char gamemap[20][26];
file.open("maze-hard.txt");
if(!file.is_open())
{
cout << "Error: Cannot open file" << endl;
return 0;
}
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 26; i++)
{
gamemap[i][j] = file.get();
cout << gamemap[i][j];
}
cout << endl;
}
It was somewhat successful, but I got a segmentation fault error. I don't know where the problem lies. Don't go hard on me for this one. I'm not all that advanced in C++.
for(int j = 0; j < 26; i++)
I'd replace that i++ with a j++.
increment j in the second cycle, not i ;)
While probably not strictly related to this particular segfault, I'd also check to make sure that the read is good for safety.
if(file.good())
{
gamemap[i][j] = file.get();
//etc etc
}