Как получить входные данные из другого файла для моей игры Судоку C, используя файл .txt

Итак, моя проблема в том, что я понятия не имею, куда идти в моей ситуации с моей программой Судоку. На данный момент у меня есть несколько программ, которые работают вместе, чтобы создать мою программу Судоку, которая ПРЕДЛАГАЕТСЯ вводить 9 строк по 9 символов в каждой, будь то пробелы или цифры.
пример:

53  7
6  195
98    6
8   6   3
4  8 3  1
7   2   6
6    28
419  5
8   79

Что программа даст:

534678912
672195348
198342567
859761423
426853791
713924856
961537284
287419635
345286179

Мои текущие программы состоят из файлов stack.h, stack.cc, sudokuboard.h sudokuboard.cc, sudoku.cc и Makefile, а также test.txt (содержит пример ввода, который у меня был выше)

программы stack.h:

struct Node {
StackElementType data;
Node *next;
};
class Stack {
public:

Stack(); //constructor
~Stack(); //deconstructor
Stack(const Stack & orig); // copy constructor
void output(ostream & ostr) const; //output method
bool empty() const; // if empty returns true
void push(const StackElementType & item); // puts new item on top of stack
void pop(); // removes top element of nonempty stack
StackElementType top() const; // returns copy of top element of a stack

private:
Node*first;
size_t _size;
}

Обратите внимание, что в этом могут быть ошибки из-за невозможности напрямую скопировать мой код, поэтому большая часть этого текста только что напечатана.

Мой стек

#include "stack.h"#include <cstdlib>
#include <cassert>

void destroy(Node *p)
{
// delete all nodes dominated by p.
while (p != NULL) {
Node *old = p;
p = p->next;
delete old;
}
}

Node *copy(Node *p)
{
// Make a deep copy of linked list dominated by p.
Node *result = NULL;
if (p != NULL) {
result = new Node;
Node *last = result;
while (p != NULL) {
// invariant: last points to a node ready to receive p's data.
last->data = p->data;
last->next = NULL;
p = p->next;
if (p != NULL) {
// there's going to more to this copy.  Get it ready.
last->next = new Node;
last = last->next;
}
}
}
return result;
}

Stack::Stack()
{
first = NULL;
}

Stack::~Stack()
{
destroy(first);
}

Stack::Stack(const Stack & orig)
{
first = copy(orig.first);
}

Stack & Stack::operator=(const Stack & rhs)
{
if (this != &rhs)
first = copy(rhs.first);
return *this;
}

void Stack::output(ostream & ostr) const
{
ostr << "<";
for(Node *p = first;p;p=p->next) {
ostr << p->data;
if (p->next)
ostr << ", ";
}
ostr << ">";
}

void Stack::push(const ElementType & item)
{
Node *born = new Node;
born->data = item;
born->next = first;
first = born;
}

void Stack::pop()
{
assert(!empty());
Node *rest = first->next;
delete first;
first = rest;
}

ElementType Stack::top() const
{
assert(!empty());
return first->data;
}

bool Stack::empty() const
{
return first==NULL;
}

Так что это просто то, что я использую для своего стека

Мой sudokuboard.h:

#include <iostream>

#define SDIM 9

class SudokuBoard {
public:
//------------------------------------------------------------------------
SudokuBoard();
// Construct a blank sudoku board
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void print(std::ostream & ostr) const;
// display it.  duh.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void place(size_t r, size_t c, char digit);
// PRE: safe(r,c,digit)
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void remove(size_t r, size_t c, char digit);
// PRE: get(r,c) == digit
//------------------------------------------------------------------------

//------------------------------------------------------------------------
char get(size_t r, size_t c) const;
// Return the digit at (r,c) on the board.  or ' ' if blank.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
bool safe(size_t r, size_t c, char digit) const;
//
//------------------------------------------------------------------------

//------------------------------------------------------------------------
bool done() const;
// Return true iff every cell has a number
//------------------------------------------------------------------------
private:
std::string rows[SDIM];
};

Пока мой sudokuboard.cc

#include <iostream>
#include <cassert>
#include "sudokuboard.h"
#define ASSERTBOUNDS assert(0 <= r and r < SDIM and 0 <= c and c < SDIM)

SudokuBoard::SudokuBoard()
{
for (size_t i = 0;i<SDIM;i++) {
rows[i] = "";
for (size_t j=0;j<SDIM;j++)
rows[i] += ' ';
}
}

void SudokuBoard::place(size_t r, size_t c, char digit)
{
ASSERTBOUNDS;
assert(safe(r,c,digit));
}

void SudokuBoard::remove(size_t r, size_t c, char digit)
{
ASSERTBOUNDS;
assert(get(r,c)==digit);
rows[r][c] = ' ';
}

char SudokuBoard::get(size_t r, size_t c) const
{
ASSERTBOUNDS;
return rows[r][c];
}void SudokuBoard::print(std::ostream & ostr) const
{
for (size_t i=0;i<SDIM;i++)
ostr << rows[i] << std::endl;
}
bool SudokuBoard::safe(size_t r, size_t c, char digit) const
{
for(size_t r=0; r<SDIM; r++)
for(size_t c=0; c<SDIM; c++)
if (get(r,c) == digit)
return false;

for(size_t c=0; c<SDIM; c++)
for(size_t r=0; r<SDIM; r++)
if (get(r,c) == digit)
return false;
return true;
}
bool SudokuBoard::done() const
{
for (size_t r=0;r<SDIM;r++)
for (size_t c=0;c<SDIM;c++)
if (rows[r][c]==' ')
return false;
return true;
}

Мой sudoku.cc сейчас довольно пустой, потому что у меня есть только общее представление о том, как преследовать мою цель. То, как я собираюсь заполнить пустые места, так это то, что я собираюсь взять одну область и ввести наименьшее возможное число в ее текущей строке / столбце, и если в ее строке / столбце есть большее число, до +1. Затем я иду вниз по колонне и так далее.

Мой вопрос заключается в том, как мне интегрировать следующие программы sudokuboard.cc и stack.cc в мой sudoku.cc. Я знаю, что мне нужно как-то получить входные данные test.txt и преобразовать каждую строку в пустую доску, но я вообще не знаю, как сформулировать входные данные cin для этого!

Другими словами, я ищу любую помощь, чтобы начать мой sudok.cc и как я должен приблизиться к этому?

sudoku.cc

#include <iostream>
#include <cassert>
#include "sudokuboard.h"#include "stack.h"
int main()
{}

Я просто хочу сказать спасибо, кто дал мне эти ответы, теперь моя лаборатория успешно работает благодаря вам, ребята! Я не могу дать никому из вас баллы, потому что мой представитель слишком низкий, но в противном случае я бы сделал это!

0

Решение

Метод, который я бы использовал для чтения текстового файла:

//Code here
std::ifstream infile("test.txt", std::ios::binary);
if(infile.is_open())
{
char szFileData[32]; //I think we can assume that each line won't be above 32 bytes
infile.getline(szFileData, 32);
do
{
//Set the cells to the data you just pulled
infile.getline(szFileData, 32);
}while(infile.good());
}
else
{
std::cout<<"Unable to open file!"<<std::endl;
}
0

Другие решения

Чтобы прочитать в файле, посмотрите на fstream. Вы можете читать из файлового потока так же, как из std :: cin.
Затем вы можете прочитать весь файл и сохранить его в std::vector<std::string> или что-то еще, это зависит от вас. Найдите контейнер, который подходит вам больше всего.

std::vector<std::string>  data;
std::string               line;
std::fstream              file("test.txt", std::in);

if (file.good())
{
while (file.eof() == false)
{
getline(file, line);
data.push_back(line);
}
}

Вы можете получить доступ к данным, выполнив data[r][c],
Я не могу проверить это прямо сейчас, поэтому могут быть небольшие ошибки, но это общая идея

0

Мой первый вопрос, почему у вас даже есть Stack учебный класс. У тебя есть
стек бесплатно, если вы используете рекурсивную функцию.

Что касается вашего вопроса: я бы использовал std::getline читать строки.
Игнорируете ли вы символы за пределами 9-го, чтобы разрешить комментарии, или
Относитесь ли вы к ним как к ошибке формата при вводе, зависит от вас. От
опыт, однако, я бы, по крайней мере, разрешил дополнительные пробелы.
Как только у вас есть линия, самое простое решение, вероятно, это заставить ее
минимум 9 символов (функция resize на строку), добавив
концевые заготовки. Затем я бы проверил, что все персонажи
цифры или пробел (std::find_ifс соответствующим
сказуемое). Это также может быть проще, если вы конвертируете пробелы в ‘0’:
если ваше внутреннее представительство использует 0 для пустого квадрата (наиболее
логичный выбор, имхо) тогда можно просто вычесть '0' с каждого
характер и назначить его на соответствующий квадрат.

Предполагая наиболее логичное представление доски (vector<int>), этот
дал бы что-то вроде:

struct TransformInputForSudoku
{
int operator()( char ch ) const
{
if ( ch == ' ' ) {
return 0;
} else if ( ! isdigit( static_cast<unsigned char>( ch ) ) ) {
return ch - '0';
} else {
throw std::runtime_error( "Illegal character" ) ;
}
}
};

std::vector<int>
getBoard( std::istream& source )
{
std::vector<int> results;
while ( results.size() < 81 ) {
std::string line;
if ( ! std::getline( source, line ) ) {
throw std::runtime_error( "Input error" );
}
line.resize( 9, ' ' );  //  extra char's are comments
std::transform( line.begin(),
line.end(),
std::back_inserter( results ),
TransformInputForSudoku() );
}
return results;
}

(Этот код объединяет проверку ввода и преобразование в одном
функциональный объект.)

0
По вопросам рекламы [email protected]