I'm still a bit new to C++, so I apologize in advance if some of what I say doesn't make sense at all.
My current goal is to take a text file that contains both words and an array of integers and read those integers into a two-dimensional array. After completing the great C++ tutorial here and using google to search for answers to every question I've had, I've finally come up with a way to do that. I'll post the code here and explain my thought process below:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
string dat_1("DAT_1");
string end_dat_1("END_DAT_1");
string dat_2("DAT_2");
string end_dat_2("END_DAT_2"); //Search strings
size_t begin;
size_t end; //Used to determine where data is located
int length; //Will store length of txt
char * buffer;
string str;
string str2; //txt in string form and substring of data, respectively
int map[8][8]; //array in which to store int data
ifstream in("data.txt");
ofstream out("output.txt"); //files to read from and write to
in.seekg(0,ios_base::end);
length = in.tellg();
in.seekg(0,ios_base::beg); //determine length of txt and return to beginning
buffer = new char[length]; //allocate memory for c_str
in.read(buffer,length);
in.close(); //copy contents of txt to buffer and close file
str = string(buffer); //convert c_str to string and place in str
delete[] buffer; //no longer need buffer
begin = str.find(dat_1);
end = str.find(end_dat_1); //find markers that denote beginning and end of data
if(begin != string::npos && end != string::npos) {
str2 = str.substr(begin + 6, end-begin+6); //create a substring of only data
buffer = new char[str2.size()+1]; //allocate memory for c_str
strcpy(buffer, str2.c_str()); //copy contents of str2 to buffer in c_str form
for(int y = 0; y < 8; y++) {
for(int x = 0; x < 8; x++) {
map[x][y] = (int) strtol(buffer, &buffer, 10);
out << map[x][y] << " ";
}
out << "\n"; //loop through data, converting numbers to integers
//strtol is used to create pointer to next number, but
//result is cast as an int since a long int is not needed
}
delete[] buffer; //data is stored; no longer need buffer
}
else {
cout<<"Could not find one of DAT_1 or END_DAT_1";
}
}
|
And here is the contents of data.txt:
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
|
Other information up here...
DAT_1
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1
0 9 0 9 0 9 0 9
2 4 6 8 8 6 4 2
1 6 0 2 1 7 6 4
3 1 4 1 5 9 2 5
2 7 1 8 2 8 1 8
6 0 2 2 1 4 1 7
END_DAT_1
DAT_2
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7
END_DAT_2
...
|
I'm copying the contents of data.txt to a string, then using the string function to find the beginning and end of the data (DAT_1 and END_DAT_1, respectively). I then cut out a substring that contains only my data so I can use it. In order to convert the data to ints, I first convert this string to a c_str, then use strtol() to convert (I would use atoi, but I'm not sure how to get more than one number that way). Since I don't need long ints, I cast the result as an int and store it in an array.
I'm concerned that this seems awfully convoluted for something that seems so simple. It seems like there are too many conversions. I convert from txt to a stream to char *, then to string to use the find functions, then to char * again so that I can convert to int, which requires a function that normally converts to long int. Am I missing something that will make the process easier? Am I on the right track, or am I coming up with complicated workarounds for something that should be simple? Or maybe this is simple in C++ terms?
Thanks for the help. I tried to struggle through as much as I could, and now that I have code up and running (and working!), I just want to make sure I'm on the right track.