Reading table from txt file.

Jan 10, 2020 at 8:01pm
Hello.
I need help guys. I've txt file with data like this :
22 55 23
11 53 21
44 12 23
12 33 23
14 45 12

and i need to put in 2D array with size [2][4]. How can i do it ?

1
2
3
4
5
6
7
   ifstream myReadFile;
   myReadFile.open("filename.txt");
   int array[2][4];
 if(myReadFile)
{
  2x for here but how ?
}


So this code reads from file, but how i Can put all data in array?
Jan 10, 2020 at 8:04pm
size [2][4] array is 8 entries, not large enough to fit your 15 entries.
I'm sure you meant size [3][5], but regardless,
you'd do something like:
1
2
3
4
5
6
7
8
9
10
int array[3][5];
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 5; j++)
    {
        int n;
        file >> n;
        array[i][j] = n;
    }
}
Last edited on Jan 10, 2020 at 8:04pm
Jan 10, 2020 at 8:06pm
you can't.
math being what it is, 2*4 is 8, and your file appears to have much more than 8 numbers.

say the file actually had 8 values, though, or the first 8 were what belonged in the array in the right order. Because you used a solid block 2d array, you can collapse it to one-d and do it with simple code.
int *ip = &array[0][0];
for(int i = 0; i < 8; i++) //8 is 2*4;
{
filevar>>ip[i];

}

if you need a flexible sized 2-d construct, you need to re-do with vectors. Vectors do not collapse this way, you can either make a 1-d and fake the 2-d access or you have to double loop and deal with the problems caused by multi dimensions.
Last edited on Jan 10, 2020 at 8:09pm
Jan 10, 2020 at 10:04pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Read a table into a vector of vector
// • All elements are the same type
// • Elements are separated by spaces
// • No element is missing/empty

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

template <typename T>
std::vector <std::vector <T>>
read_table_of( std::istream& ins )
{
  std::vector <std::vector <T>> result;
  std::string s;
  while (getline( ins, s ))
  {
    std::vector <T> row;
    std::istringstream ss( s );
    T value;
    while (ss >> value) row.emplace_back( value );
    result.emplace_back( row );
  }
  return result;
}

// A simple example to run

#include <sstream>
#include <utility>

int main()
{
  std::istringstream input(
    "1 2 3\n"
    "4 5 6\n"
    "7 8 9\n"
  );

  auto table = read_table_of <int> ( input );
  
  for (auto record : table)
  { 
    for (auto field : record)
      std::cout << field << " ";
    std::cout << "\n";
  }
}

If you are stuck using arrays, let us know.
Jan 11, 2020 at 4:18pm
Ok, i have something like this :

1
2
3
4
5
6
7
8
9
10
int array[3][5];
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 5; j++)
    {
        int n;
        file >> n;
        array[i][j] = n;
    }
}


its working properly, but what if my data in file looks like this:
122,754,897,154,
643,123,231,351,

numbers are separated by coma, how i can put each number in 2D array[2][4]?
Jan 11, 2020 at 4:32pm
Look into std::getline.
http://www.cplusplus.com/reference/string/string/getline/
(1) istream& getline (istream& is, string& str, char delim);

Use ',' (comma) as the delimiter and experiment with that.

If you use this method, however, each result will be a string, and you'll have to convert the string into an int. (std::stoi can do this).
http://www.cplusplus.com/reference/string/stoi/
Last edited on Jan 11, 2020 at 4:34pm
Jan 11, 2020 at 5:26pm
A simple but less robust solution for dealing with the commas:

1
2
3
4
5
6
7
8
9
10
11
12
13
const int Rows = 2, Cols = 4;
int a[Rows][Cols];

for (int row = 0; row < Rows; ++row)
{
    for (int col = 0; col < Cols; ++col)
    {
        int n;
        char ch;
        file >> n >> ch;
        a[row][col] = n;
    }
}

Last edited on Jan 11, 2020 at 5:27pm
Jan 11, 2020 at 6:38pm
Honestly that's much simpler and probably just as robust.
Only using getline means extra logic needed to remove the newlines as well.
Jan 11, 2020 at 7:24pm
It depends on his exact input. He shows a comma at the end of the line as well as between values. If that last comma isn't there, then the above simple solution will "eat" the first digit of the first number on the next line.

Some combination of our two approaches might be best. And combining with Duthomhas's approach allows any number of lines and even different numbers of values-per-line.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using Table = std::vector<std::vector<int>>;

Table read_table(const std::string& filename) {
    Table table;
    std::ifstream in(filename);
    for (std::string line; std::getline(in, line); ) {
        if (line.find_first_not_of(" \t") == line.npos)
            continue; // skip blank lines
        table.resize(table.size() + 1);
        std::istringstream iss(line);
        for (int n; iss >> n; ) {
            table.back().push_back(n);
            char ch;
            iss >> ch; // eat comma (if not present at end of line, iss enters failed state)
        }
    }
    return table;
}

void print_table(const Table& table) {
    for (const auto& row: table) {
        for (int n: row)
            std::cout << std::setw(4) << n << ' ';
        std::cout << '\n';
    }
}

int main() {
    Table table = read_table("input_file");
    print_table(table);
}

Last edited on Jan 11, 2020 at 7:25pm
Jan 12, 2020 at 1:17am
ts working properly, but what if my data in file looks like this:
122,754,897,154,
643,123,231,351,

numbers are separated by coma, how i can put each number in 2D array[2][4]?


You have 2 rows of data with 4 pairs of a number followed by a comma.

End of story?
Topic archived. No new replies allowed.