Reputation: 1056
I'm trying to create a program that reads in and solves incomplete 9x9 sudoku boards from a text file. One of the boards might look like this:
N
145369287
629785431
783412569
567148392
938527 14
214936758
851 74623
492853 76
376291845
I need to print out the board read in, which I'm doing by just using getline and printing the string, and then store each digit into an array, blanks can be converted to zeroes for the purpose of evaluation. If I tried to read the board in as straight ints then it would try to read all the digits of a row as one int until a space or a newline was reached, and if I try to read it in char by char with get(), I run into problems again with newlines, and I would then have to convert the array of chars to an array of ints for evaluation which I think I will run into problems with as well. This is my code so far, I figured using an istringstream would be convenient but then realized that I would have to have more for loops, so a solution without it would be ideal. Not allowed to use vectors or fancy modules or structs anything like that, it is a class assignment.
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>
using namespace std;
int main() {
ifstream infile("sudoku_infile.txt");
ofstream outfile("sudoku_outfile.txt");
int board[9][9];
char n;
char c;
string str;
stringstream into;
while (infile >> n){
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
getline(infile, str);
cout << str << "\n";
into << str;
}
return 0;
}
EDIT: Ok, I've devised a solution on my own by trying to convert chars to ints and putting them in an array, but it doesn't seem to be working:
while (infile >> str){
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
getline(infile, str);
cout << str << "\n";
for (int z = 0; z < 9; z++){
if (isdigit(str[z])){
d = str[z] - '0';
}
else{
d = 0;
}
board[i][j] = d;
}
}
for (int m = 0; m < 9; m++){
for (int f = 0; f < 9; f++)
cout << board[m][f];
cout << endl;
}
}
I get this as output:
145369287
629785431
783412569
567148392
938527 14
214936758
851 74623
492853 76
376291845
071924836
555555555
555555555
555555555
555555555
555555555
555555555
555555555
555555555
Upvotes: 1
Views: 154
Reputation: 409136
This can easily be done with one of the standard algorithm functions, namely std::copy
. You can use it with iterator helpers like std::istream_inserter
and std::back_inserter
.
Use the above functions to put the integers into a std::vector
.
After you're done with the basics, learning to use the standard library will really help you.
For example, even though you can't use it for this assignment, the above mentioned functions could be used like this:
std::vector<std::string> vs;
std::copy(std::istream_iterator<std::string>(infile),
std::istream_iterator<std::string>(),
std::back_inserter(vs));
After the above, the vector vs
will contain all white-space delimited string from the infile
stream.
To then get it into a board, you could to like this:
std::array<std::array<int, 9>, 9> board;
int i = 0;
for (const std::string& s : vs)
{
int j = 0;
for (const char& c : s)
board[i][j++] = c - '0';
++i;
}
Upvotes: 0
Reputation: 8961
You have to make sure, that your file just contains up to 9*9 characters - otherwise it will run out of bounds this way - but it's easy to add a bounds check in there. Because '0' starts in ASCII at index 48, I'm calculating the char value minus the magic number 48. However you still have to add a check for ' ' by yourself (otherwise it gets initalized with -16), but I'm sure you can do it!
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
int main(int argc, char **argv) {
std::ifstream infile("sudoku_infile.txt");
std::ofstream outfile("sudoku_outfile.txt");
int board[9][9];
size_t index = 0;
std::string str;
while (std::getline(infile, str)){
//std::cout << str << "\n";
for (size_t i = 0; i < str.size(); i++, index++){
board[index%9][index/9] = str[i] - '0';
}
}
return 0;
}
Upvotes: 2