How to get input from another file for my Sudoku game C using a .txt file

瘦欲@ 提交于 2019-12-12 05:27:30

问题


Alright so my problem is that I have no idea where to go in my situation with my Sudoku Program. As of right now I have multiple programs that work together to create my Sudoku program which is SUPPOSED to take input of 9 lines with 9 characters each whether it be just spaces or numbers. example:

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

What the program would yield would be:

534678912
672195348
198342567
859761423
426853791
713924856
961537284
287419635
345286179

My current programs consist of the files stack.h, stack.cc, sudokuboard.h sudokuboard.cc, sudoku.cc, and Makefile, as well as test.txt(consists the example of input i had above)

the programs 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;
}

Note that there may be misspellings in this due to having to being unable to copy my code directly so most of this is freshly typed out.

My stack.cc is

#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;
}

So this is simply what I am using for my stack

My 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];
};

While my 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;
}

My sudoku.cc right now is pretty much blank because I have only a general idea on how to pursue my goal. The way I am going to fill in the empty spaces is that I am going to take to take a single area and put in the smallest possible number in its current row/column and if there is a higher number in its row/column is goes up +1. I then go down the column and so on.

My question is how do i integrate the following programs of sudokuboard.cc and stack.cc in my sudoku.cc. I know I have to get the input of test.txt some how and convert each of the lines to the empty board, but I don't know how to phrase the cin input for that at all!

In other words I am looking for any help to get my sudok.cc started and how should I approach it?

sudoku.cc

#include <iostream>
#include <cassert>
#include "sudokuboard.h"
#include "stack.h"

int main()
{


}

I just want to say thank you who gave me these answers, now my lab is well on its way thanks to you guys! I cannot give any of you points b/c my rep is too low but otherwise i would!


回答1:


The method I would use to read the text file:

//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;
}



回答2:


To read in a file, look at fstream. You can read from a file stream as you would from std::cin. You could then read the whole file and store it in a std::vector<std::string> or something else, it's up to you. Find the container that suits you the most to use.

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);
   }
}

You can then access the data by doing data[r][c]. I can't test it right now so there may be some slight errors, but it's the general idea




回答3:


My first question is why you even have a Stack class. You have a stack for free if you use a recursive function.

With regards to your question: I'd use std::getline to read the lines. Whether you ignore characters beyond the 9th, to allow comments, or whether you treat them as a format error on input is up to you. From experience, however, I'd at least allow additional trailing whitespace. Once you have the line, the easiest solution is probably to force it up to a minimum of 9 characters (function resize on the string), adding trailing blanks. I'd then check that all of the characters are either digits or the space character (std::find_if, with an appropriate predicate). It might also be simpler if you converted spaces into '0': if your internal representation uses 0 for an empty square (the most logical choice, IMHO), you can then simply subtrace '0' from each character and assign it to the appropriate square.

Assuming the most logical representation of the board (vector<int>), this would give something like:

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;
}

(This code combines input validation and conversion in a single functional object.)



来源:https://stackoverflow.com/questions/12722392/how-to-get-input-from-another-file-for-my-sudoku-game-c-using-a-txt-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!