2

(C++) I've created a function to open the text file and assign the contents to an array. The first 2 elements in the array are the size of the grid. However, if either or both of the first 2 numbers are double digits, it doesnt read them in as double digits. Is there any way of doing this?

int openMap()
{
    std::string fileName;

    std::cout << "Please enter the file name with extension that you want to open: ";
    std::cin >> fileName;

    system("CLS");

    std::ifstream file(fileName);           //OPENS MAP FILE

    int tmp;
    int i = 0;

    if (!file.is_open())                    //CHECKS IF THE MAP FILE HAS OPENED CORRECTLY
    {
        std::cout << "Error Occured!\nCould not open file.";

        return 0;
    }

    while (!file.eof())                     //READS THE MAP FILE AND PASSES THE INFORMATION INTO AN ARRAY
    {
        file >> tmp;
        checkNumber(tmp);
        if (valid == true)                  //IF THE CHARACTER IS NOT A NUMBER THEN IT WONT BE PASSED INTO THE ARRAY
        {
            tmpArray[i] = tmp;
            i++;
            valid = false;
        }
        row = tmpArray[1];              //ASSIGNS THE FIRST 2 NUMBERS OF THE MAP FILE TO ROW AND COL VARIABLES
        col = tmpArray[0];
    }

    return row, col;
}

I would assume I have to rewrite

file >> tmp

in some sort of different way, but not sure how. Is there a way to scan through the text file until it hits a whitespace?

The text file contents looks like this

6 4 0 0 1 0 0 0 2 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 3 0

(the 6 or 4 or both can be double digits instead)

Edit:

    for (int j = 0; j < row; j++)
    {
        for (int k = 0; k < col; k++)
        {
            _map[j][k] = tmpArray[l];
            std::cout << _map[j][k] << " ";
            l++;
        }
    }   
  • 1
    `while (!file.eof())` read here [https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – drescherjm Dec 10 '19 at 15:52
  • I'm assuming checkNumber sets valid? If so, then valid = false doesn't really do anything. If checkNumber only sets valid = true then you should also have it set to false when it's not a number. – Bobby Tables Dec 10 '19 at 15:58
  • *"it doesnt read them in as double digits"* What does it do? What outcome do you expect, and what do you observe instead? `file >> tmp` should read arbitrary integers just fine; to the extent there is a problem, it must lie elsewhere. It would be best to show a [mcve] – Igor Tandetnik Dec 10 '19 at 16:01
  • for example, if the text file starts with 10 10, my code reads it as 1 0 1 0. So my array values are array[0] = 1, array[1] = 0, array[2] = 1, array[3] = 0. Want I want to happen is have array[0] = 10, array[1] = 10. – AnayTekstar Dec 10 '19 at 16:05
  • @BobbyTables Thanks, I've removed the line from my code. – AnayTekstar Dec 10 '19 at 16:10
  • @AnayTekstar where is temp array declared and what type is it? – Bobby Tables Dec 10 '19 at 16:13
  • tmpArray is delcared as a global variable. and it is a char type. char tmpArray[10000]; – AnayTekstar Dec 10 '19 at 16:14
  • @AnayTekstar you should at least be getting a compiler warning(at least) complaining about assigning an int to a char. Make your array an array of ints. – Bobby Tables Dec 10 '19 at 16:39
  • My guess would be, in the actual code you are running `tmp` is of type `char` and not `int`. Then of course `file >> tmp` reads a single character and not an integer. – Igor Tandetnik Dec 10 '19 at 21:53

3 Answers3

1

There's quite a number of bugs in the code, you should probably use a debugger to step through and identify which parts of your program don't behave as expected.

while(!file.eof())
    file >> tmp;
    checkNumber(tmp);
    if (valid == true)                  //IF THE CHARACTER IS NOT A NUMBER THEN IT WONT BE PASSED INTO THE ARRAY
    {
        tmpArray[i] = tmp;
        i++;
        valid = false;
    }
    row = tmpArray[1];              //ASSIGNS THE FIRST 2 NUMBERS OF THE MAP FILE TO ROW AND COL VARIABLES
    col = tmpArray[0];

You set row=tmpArray[1] and col = tmpArray[0] every iteration of the loop which is not only unnecessary but also incorrect, especially since row=tmpArray[1] is being executed at i=0 when nothing has been placed in tmpArray[1] yet.

EDIT: This is a lot smaller, less error prone due to less variables and type conversions, and easier to read:

int row,col;

//Add error checking here
cin >> col;
cin >> row;

cout << "Cols: " << col << " Rows: " << row << endl;

vector<vector<int> >_map(row, vector<int>(col,0));

for(int j=0; j < row; j++)
{
    for(int k=0; k < col; k++)
    {
        int tmp;
        cin >> tmp;
        //Add error checking for tmp
        _map[j][k] = tmp;
        cout << _map[j][k] << endl;
    }
}
Bobby Tables
  • 191
  • 2
  • 15
  • I tried to use an int array and made the tmp variable an int as well, but this doesnt seem to work. Im not sure what you mean by use to_string on the element. the array is used to temporarily store the information. I then use the array to assign the elements to a vector, and i print the vector out. I have added the code in the question at the bottom under Edit: – AnayTekstar Dec 10 '19 at 16:49
  • @AnayTekstar I edited my answer to give you a better solution – Bobby Tables Dec 10 '19 at 17:14
1

There are some problems with your code. First the return type of your function is int but you are returning multiple values. Here is a complete running code which should solve your problem.

#include <iostream>
#include <fstream>
#include <vector>

std::vector< std::vector<int> > openMap() {
    std::string fileName;

    std::cout << "Please enter the file name with extension that you want to open: ";
    std::cin >> fileName;

    std::fstream myfile(fileName, std::ios_base::in);
    int row, col;
    myfile >> row;
    myfile >> col;

    int a;
    std::vector< std::vector<int> > retval;
    for (int i = 0; i < row; i++) {
        std::vector<int> v1;
        for (int j = 0; j < col; j++) {
            myfile >> a;
            v1.push_back(a);
        }
        retval.push_back(v1);
    }
    return retval;
}


int main(int argc, char * argv[])
{
    std::vector< std::vector<int> > _map = openMap();

    for(int i = 0; i < _map.size(); i++) {
        for (int j = 0; j < _map[i].size(); j++) {
            std::cout << _map[i][j] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}
anas17in
  • 161
  • 9
0

I guess that not so many people will be interested. But please see below a possible solution to your problem.

The code uses modern C++ algorithms.

It is very simple and straightforward.

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>


int main() {

    // Ask user, to give a filename
    std::cout << "Please enter the file name with extension that you want to open: ";

    // Get the filename from the user
    if (std::string fileName; std::cin >> fileName) {

        // Open the file and check, if it is open
        if (std::ifstream sourceFile(fileName); sourceFile) {

            // Read the number of rows and columns of the matrix
            if (size_t numberOfColumns, numberOfRows;  sourceFile >> numberOfColumns >> numberOfRows) {

                // Create a matrix with the given number of rows and columns
                std::vector<std::vector<int>> result(numberOfRows, std::vector<int>(numberOfColumns, 0));

                // Read data from the input stream and put it into the matrix
                for (size_t i = 0; i < numberOfRows; ++i) {
                    std::copy_n(std::istream_iterator<int>(sourceFile), numberOfColumns, result[i].begin());
                }

                // Print result. Go through all lines and then copy line elements to std::cout
                std::for_each(result.begin(), result.end(), [](std::vector<int>& c) {
                    std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "\n";   });
            }
        }
        else {
            std::cerr << "\n*** Error: Could not open source File\n\n";
        }
    }
    return 0;
}
A M
  • 14,694
  • 5
  • 19
  • 44