I hope you have a good day.
I'd like to input 2 dimensional array from text file. But my code doesn't work..
#pragma disable (warnning:c4996)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<fstream>
#include<conio.h>
int main()
{
std::ifstream arrival; std::ifstream departure;
arrival.open("arrival.txt"); departure.open("departure.txt");
int i, j, l = 0;
char temp;
if (arrival.is_open() && departure.is_open()) {
temp = arrival.get();
while (temp != EOF) {
if (temp == '\n')
l ;
temp = arrival.get();
}
}
else
printf("error");
// file read
int** arr = new int*[l];
for (i = 0; i < l; i )
arr[i] = new int[3];
for (i = 0; i < l; i ) {
for (j = 0; j < 3; j )
arrival >> arr[i][j];
}
for (i = 0; i < l; i ) {
for (j = 0; j < 3; j )
printf("%d ", (int)arr[i][j]);
}
_getch();
delete[] arr;
arrival.close();
departure.close();
return 0;
}
this is my code, and
arrival
2018 01 05
2018 02 03
2019 04 03
2019 08 08
2020 07 08
2018 03 28
2018 05 04
2018 08 30
2019 01 06
2019 09 21
2020 02 18
this is the text file.
I assume in
arrival >> arr[i][j];
this part, it doesn't get value from the file. I have no idea how to solve this probliem
thank you for reading. Bless you thank you.
CodePudding user response:
So the problem is that you read to the end of the file looking for newlines. Then you start to read your data. The problem is that you are still at the end of the file, so there is no data.
You need to rewind the file before you start reading the data.
// file read
arrival.seekg(0); // rewind the input file back to the start
int** arr = new int*[l];
CodePudding user response:
Here's a different solution using:
std::vector
andstd::array
for holding the list of values read from the file.std::istringstream
to parse each file line into an array of values.fmt::print
to print each array of values.
You can just substitute the example's std::istringstream arrival
for a std::ifstream arrival
; they are both input streams.
By using std::vector
, which you can grow dynamically, you don't need to read the input stream twice. Instead, just push_back
each line read from the input stream into the vector.
#include <array>
#include <fmt/ranges.h>
#include <sstream> // istringstream
#include <vector>
int main() {
std::istringstream arrival{
"2018 01 05\n"
"2018 02 03\n"
"2019 04 03\n"
"2019 08 08\n"
"2020 07 08\n"
"2018 03 28\n"
"2018 05 04\n"
"2018 08 30\n"
"2019 01 06\n"
"2019 09 21\n"
"2020 02 18"
};
std::vector<std::array<int, 3>> lines{};
for (std::string current_line{}; std::getline(arrival, current_line);) {
std::istringstream iss{current_line};
std::array<int, 3> current_line_numbers{};
iss >> current_line_numbers[0]
>> current_line_numbers[1]
>> current_line_numbers[2];
lines.push_back(current_line_numbers);
}
for (auto&& line : lines) {
fmt::print("{}\n", fmt::join(line, " "));
}
}
// Outputs:
//
// 2018 1 5
// 2018 2 3
// 2019 4 3
// 2019 8 8
// 2020 7 8
// 2018 3 28
// 2018 5 4
// 2018 8 30
// 2019 1 6
// 2019 9 21
// 2020 2 18
CodePudding user response:
This is what you can do with the 4 'basic' libraries vector
, string
, fstream
and iostream
. It is an example for "arrivals.txt" only:
#include<vector>
#include<string>
#include<fstream>
#include<iostream>
int main() {
std::ifstream arrivals; // open the file
arrivals.open("arrivals.txt");
std::vector<std::vector<int>> matrix; // 2D container
int l=0;
std::string unused;
while (std::getline(arrivals,unused)) // count the lines
l;
arrivals.clear(); // go back to start
arrivals.seekg(0);
matrix.resize(l); // resizing matrix
for (int i=0; i<l; i ) { // fill the matrix
matrix[i].resize(3); // resizing row
for (int j=0; j<3; j )
arrivals >> matrix[i][j];
}
arrivals.close(); // close the file
for (int i=0; i<l; i ) { // print the matrix
for (int j=0; j<3; j )
printf("d ",matrix[i][j]);
printf("\n");
}
}
The most important things to remember are
- to resize the vector before filling in a new element (easier than dynamic allocation!)
- to go back to the start of the text file after counting the line (you could if you want, also close the file and open again for reading).