From int to char* without strings, and a inconvenient with fstream - c++

I need help in an "homework". I cant get to work this code because I cant convert from int to *char. The big problem is that I cant use strings. This is the code:
//This is in a class
void Interfaz::guardarFCS() {
char *nombreArchivo = vent.pedirTxt("por favor inserte un nombre para el archivo");
exportar.setFileName(nombreArchivo,2);
int ancho = elMapa.getterAncho();
int alto = elMapa.getterAlto();
int estadoCasilla;
int l;
int k;
for( l = 0; l<ancho; l++) {
for( k = 0; k<alto; k++) {
estadoCasilla = elMapa.casillaMapaInt(l,k);
if(estadoCasilla==1) {
exportar.escribir("[");
exportar.escribir(l);
exportar.escribir("],[");
exportar.escribir(k);
exportar.escribir("]\n");
}
}
}
}
where escribir is just an ofstream with <<whatIsSend.
in here I cant create a ofstream variable
#ifndef Exportador_H
#define Exportador_H
class Exportador {
//variables
char fileName[255];
std::ofstream archivoIn;
public:
Exportador();
void setFileName(char*,int);
void cargar(char*);
void crear();
void escribir(char*);
void guardarFcs(Mapa);
~Exportador();
};
#endif
the only way to make it work would be to create a new variable for each method since the problem would be using class-declaration for non-member at class scope, if I don't use the std:: another error would arraise called 'ofstream' does not name a type.
either way for at least reading my code. Any sugestions would be welcome

I don't fully see what you are asking, but this should work:
void Exportador::escribir(int i)
{
char convertedToText[10] = {0};
// convert to text, this is the exericse
// (use
// - while loop,
// - i=i/10 and
// - i%10)
// don't forget to null-terminate
archivoIn << convertedToText;
}
I'm not showing you the actual conversion (hint: itoa might be what you want if you're allowed to use it), as that would remove the exercise from the homework

Related

Using a 2D array for a game map in C++

Software: Visual Studio 2017 Community
Hi, everybody,
I am making a simple 2d console game in C++ (perhaps very simplified Dwarf Fortress if you know it).
And I want a map to be displayed in console with ASCII.
Something like this:
I have a WorldMap class declared in the header file(simplified version).
And I declare a 2d array inside it.
#pragma once
#include <iostream>
class WorldMap
{
public:
WorldMap();
virtual ~WorldMap();
private:
int worldWidth;
int worldHeight;
char worldMap; // Declare a variable that will hold all the characters for the map
};
And then define it in the .cpp file:
#include "WorldMap.h"
#include <algorithm>
WorldMap::WorldMap()
{
worldWidth = 50;
worldHeight = 50;
worldMap[50][50]; // Define the map array
// And then here I will also somehow need to be able to fill the whole map with '.' symbols, and so on
}
So that is the basic idea of what I am trying to achieve. The reason why I can't define the array size immediately is because I want to be able to choose the size of the map when the map is created.
I have already tried:
The code above.
Error:
error C2109: subscript requires array or pointer type
Declaring 2d array as char worldMap[][]; and then defining it as worldMap[50][50]; .
Error:
error C2087: 'worldMap': missing subscript
warning C4200: nonstandard extension used: zero-sized array in struct/union
message : This member will be ignored by a defaulted constructor or copy/move assignment operator
Declaring 2d array as char worldMap[worldWidth][worldHeight];, expecting that when the object is created, the width and height variables will be defined first, and then they will define the array.
Error:
error C2327: 'WorldMap::worldWidth': is not a type name, static, or enumerator
error C2065: 'worldWidth': undeclared identifier
error C2327: 'WorldMap::worldHeight': is not a type name, static, or enumerator
error C2065: 'worldHeight': undeclared identifier
Using char* worldMap; and char** worldMap, but so far I can't even understand how double pointer works, yet char* worldMap actually works with a 1D array without errors, until I start accessing values of the elements in the array.
I suppose a workaround would be to use a string or 1D char array and when displaying it just use mapWidth to end line each 50 characters for example, which will give the same result. But I feel like that's not a good way to achieve this since I will need to access x and y coords of this map and so on.
I guess what I am asking is:
What's the best way of declaring a 2d array for a class and then defining it in the object?
What's the best way to store a map for such a console game? (Not necessarily using arrays)
Thank you for reading. I will really appreciate any help, even just ideas and tips might push me in the right direction :)
What's the best way of declaring a 2d array for a class and then defining it in the object?
What's the best way to store a map for such a console game? (Not necessarily using arrays)
This is not "the best way" but it's one way of doing it.
Create a class wrapping a 1D std::vector<char>.
Add operator()s to access the individual elements.
Add misc. other support functions to the class, like save() and restore().
I've used your class as a base and tried to document what it's doing in the code: If some of the functions I've used are unfamiliar, I recommend looking them up at https://en.cppreference.com/ which is an excellent wiki that often has examples of how to use the particular function you read about.
#include <algorithm> // std::copy, std::copy_n
#include <filesystem> // std::filesystem::path
#include <fstream> // std::ifstream, std::ofstream
#include <iostream> // std::cin, std::cout
#include <iterator> // std::ostreambuf_iterator, std::istreambuf_iterator
#include <vector> // std::vector
class WorldMap {
public:
WorldMap(unsigned h = 5, unsigned w = 5) : // colon starts the initializer list
worldHeight(h), // initialize worldHeight with the value in h
worldWidth(w), // initialize worldWidth with the value in w
worldMap(h * w, '.') // initialize the vector, size h*w and filled with dots.
{}
// Don't make the destructor virtual unless you use polymorphism
// In fact, you should probably not create a user-defined destructor at all for this.
//virtual ~WorldMap(); // removed
unsigned getHeight() const { return worldHeight; }
unsigned getWidth() const { return worldWidth; }
// Define operators to give both const and non-const access to the
// positions in the map.
char operator()(unsigned y, unsigned x) const { return worldMap[y*worldWidth + x]; }
char& operator()(unsigned y, unsigned x) { return worldMap[y*worldWidth + x]; }
// A function to print the map on screen - or to some other ostream if that's needed
void print(std::ostream& os = std::cout) const {
for(unsigned y = 0; y < getHeight(); ++y) {
for(unsigned x = 0; x < getWidth(); ++x)
os << (*this)(y, x); // dereference "this" to call the const operator()
os << '\n';
}
os << '\n';
}
// functions to save and restore the map
std::ostream& save(std::ostream& os) const {
os << worldHeight << '\n' << worldWidth << '\n'; // save the dimensions
// copy the map out to the stream
std::copy(worldMap.begin(), worldMap.end(),
std::ostreambuf_iterator<char>(os));
return os;
}
std::istream& restore(std::istream& is) {
is >> worldHeight >> worldWidth; // read the dimensions
is.ignore(2, '\n'); // ignore the newline
worldMap.clear(); // empty the map
worldMap.reserve(worldHeight * worldWidth); // reserve space for the new map
// copy the map from the stream
std::copy_n(std::istreambuf_iterator<char>(is),
worldHeight * worldWidth, std::back_inserter(worldMap));
return is;
}
// functions to save/restore using a filename
bool save(const std::filesystem::path& filename) const {
if(std::ofstream ofs(filename); ofs) {
return static_cast<bool>(save(ofs)); // true if it suceeded
}
return false;
}
bool restore(const std::filesystem::path& filename) {
if(std::ifstream ifs(filename); ifs) {
return static_cast<bool>(restore(ifs)); // true if it succeeded
}
return false;
}
private:
unsigned worldHeight;
unsigned worldWidth;
// Declare a variable that will hold all the characters for the map
std::vector<char> worldMap;
};
Demo
There is no best way to do anything*. It's what works best for you.
From what I understand you want to make a dynamic 2D arrays to hold your char of world map. You have a lot of options to do this. You can have a worldMap class nothing wrong with that. If you want dynamic 2D arrays just make functions out of this kind of logic.
#include <iostream>
#include <vector>
int main() {
int H = 10, W = 20;
char** map = NULL; //This would go in your class.H
//Make a function to allocate 2D array
map = new char* [H];
for (int i = 0; i < H; i++) {
map[i] = new char[W];
}
//FILL WITH WHATEVER
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
map[i][j] = 'A';
}
}
//do what ever you want like normal 2d array
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
std::cout << map[i][j] << " ";
}
std::cout << std::endl;
}
//Should always delete when or if you want to make a new one run time
for (int i = 0; i < H; i++)
delete[] map[i];
delete[] map;
map = NULL;
//Also you can use vectors
std::cout << "\n\n With vector " << std::endl;
std::vector<std::vector<char>> mapV;
//FILL WITH WHATEVER
for (int i = 0; i < H; i++) {
std::vector<char> inner;
for (int j = 0; j < W; j++) {
inner.push_back('V');
}
mapV.push_back(inner);
}
//do what ever you want kind of like a normal array
//but you should look up how they really work
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
std::cout << mapV[i][j] << " ";
}
std::cout << std::endl;
}
mapV.clear();
return 0;
}

Using an allocated structure data in an std::thread

I ran into a little problem programming something, I've looked around but I didn't seem to find out the answer.
I'll spare you useless code.
Here are the declarations:
struct one {
std::string string1, string2;
bool boolean;
};
struct two {
std::string string3, string4;
bool boolean;
};
void function(uint first_parameter, one **first, two **second);
And here is what the main looks like:
int main()
{
one *passes;
two *users;
//...
passes = new one[size_one]();
users = new two[size_two]();
//Filling the arrays...
std::thread t[PARTS];
for (int start = 0; start < PARTS; start++)
t[start] = std::thread(function, first_parameter, &passes, &users);
for (int i = 0; i < PARTS; i++)
t[i].join();
}
Whenever I try to access an element of one of my structures (allocated on the free store) in my thread function, (I typically would access it like so: (*first)[0].string1[0]) I do not get the string1 I normally can access in main. Aren't the std::strings located in the free store?
check your function to have valid types of parameters.
this example bellow works nice.
#include <iostream>
typedef struct _one
{
std::string first_str;
std::string second_str;
bool check;
} one;
void do_something(one** passes)
{
one* original = *passes;
one first = original[0];
std::cout << first.first_str; // -> hello
// the same
std::cout << (*passes)[0].first_str;
}
int main()
{
one* passes = nullptr;
passes = new one[10];
passes[0].first_str = "hello";
do_something(&passes);
}

C++ Declaring arrays in class and declaring 2d arrays in class

I'm new with using classes and I encountered a problem while delcaring an array into a class. I want to initialize a char array for text limited to 50 characters and then replace the text with a function.
#ifndef MAP_H
#define MAP_H
#include "Sprite.h"
#include <SFML/Graphics.hpp>
#include <iostream>
class Map : public sprite
{
private:
char mapname[50];
int columnnumber;
int linenumber;
char casestatematricia[];
public:
void setmapname(char newmapname[50]);
void battlespace(int column, int line);
void setcasevalue(int col, int line, char value);
void printcasematricia();
};
#endif
By the way I could initialize my 2d array like that
char casestatematricia[][];
I want later to make this 2d array dynamic where I enter a column number and a line number like that
casestatematricia[linenumber][columnnumber]
to create a battlefield.
this is the cpp code so that you have an idea of what I want to do.
#include "Map.h"
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
void Map::setmapname(char newmapname[50])
{
this->mapname = newmapname;
}
void Map::battlespace(int column, int line)
{
}
void Map::setcasevalue(int col, int line, char value)
{
}
void Map::printcasematricia()
{
}
thank you in advance.
Consider following common practice on this one.
Most (e.g. numerical) libraries don't use 2D arrays inside classes.
They use dynamically allocated 1D arrays and overload the () or [] operator to access the right elements in a 2D-like fashion.
So on the outside you never can tell that you're actually dealing with consecutive storage, it looks like a 2D array.
In this way arrays are easier to resize, more efficient to store, transpose and reshape.
Just a proposition for your problem:
class Map : public sprite
{
private:
std::string mapname;
int columnnumber;
int linenumber;
std::vector<char> casestatematricia;
static constexpr std::size_t maxRow = 50;
static constexpr std::size_t maxCol = 50;
public:
Map():
casestatematricia(maxRow * maxCol, 0)
{}
void setmapname(std::string newmapname)
{
if (newmapname.size() > 50)
{
// Manage error if you really need no more 50 characters..
// Or just troncate when you serialize!
}
mapname = newmapname;
}
void battlespace(int col, int row);
void setcasevalue(int col, int row, char value)
{
// check that col and line are between 0 and max{Row|Column} - 1
casestatematricia[row * maxRow + col] = value;
}
void printcasematricia()
{
for (std::size_t row = 0; row < maxRow; ++row)
{
for (std::size_t col = 0; col < maxCol; ++col)
{
char currentCell = casestatematricia[row * maxRow + col];
}
}
}
};
For access to 1D array like a 2D array, take a look at Access a 1D array as a 2D array in C++.
When you think about serialization, I guess you want to save it to a file. Just a advice: don't store raw memory to a file just to "save" time when your relaunch your soft. You just have a non portable solution! And seriously, with power of your computer, you don't have to be worry about time to load from file!
I propose you to add 2 methods in your class to save Map into file
void dump(std::ostream &os)
{
os << mapname << "\n";
std::size_t currentRow = 0;
for(auto c: casestatematricia)
{
os << static_cast<int>(c) << " ";
++currentRow;
if (currentRow >= maxRow)
{
currentRow = 0;
os << "\n";
}
}
}
void load(std::istream &is)
{
std::string line;
std::getline(is, line);
mapname = line;
std::size_t current_cell = 0;
while(std::getline(is, line))
{
std::istringstream is(line);
while(!is.eof())
{
char c;
is >> c;
casestatematricia[current_cell] = c;
++current_cell;
}
}
}
This solution is only given for example. They doesn't manage error and I have choose to store it in ASCII in file. You can change to store in binary, but, don't use direct write of raw memory. You can take a look at C - serialization techniques (just have to translate to C++). But please, don't use memcpy or similar technique to serialize
I hope I get this right. You have two questions. You want know how to assign the value of char mapname[50]; via void setmapname(char newmapname[50]);. And you want to know how to create a dynamic size 2D array.
I hope you are comfortable with pointers because in both cases, you need it.
For the first question, I would like to first correct your understanding of void setmapname(char newmapname[50]);. C++ functions do not take in array. It take in the pointer to the array. So it is as good as writing void setmapname(char *newmapname);. For better understanding, go to Passing Arrays to Function in C++
With that, I am going to change the function to read in the length of the new map name. And to assign mapname, just use a loop to copy each of the char.
void setmapname(char *newmapname, int length) {
// ensure that the string passing in is not
// more that what mapname can hold.
length = length < 50 ? length : 50;
// loop each value and assign one by one.
for(int i = 0; i < length; ++i) {
mapname[i] = newmapname[i];
}
}
For the second question, you can use vector like what was proposed by Garf365 need to use but I prefer to just use pointer and I will use 1D array to represent 2d battlefield. (You can read the link Garf365 provide).
// Declare like this
char *casestatematricia; // remember to initialize this to 0.
// Create the battlefield
void Map::battlespace(int column, int line) {
columnnumber = column;
linenumber = line;
// Clear the previous battlefield.
clearspace();
// Creating the battlefield
casestatematricia = new char[column * line];
// initialise casestatematricia...
}
// Call this after you done using the battlefield
void Map::clearspace() {
if (!casestatematricia) return;
delete [] casestatematricia;
casestatematricia = 0;
}
Just remember to call clearspace() when you are no longer using it.
Just for your benefit, this is how you create a dynamic size 2D array
// Declare like this
char **casestatematricia; // remember to initialize this to 0.
// Create the battlefield
void Map::battlespace(int column, int line) {
columnnumber = column;
linenumber = line;
// Clear the previous battlefield.
clearspace();
// Creating the battlefield
casestatematricia = new char*[column];
for (int i = 0; i < column; ++i) {
casestatematricia[i] = new char[line];
}
// initialise casestatematricia...
}
// Call this after you done using the battlefield
void Map::clearspace() {
if (!casestatematricia) return;
for(int i = 0; i < columnnumber; ++i) {
delete [] casestatematricia[i];
}
delete [][] casestatematricia;
casestatematricia = 0;
}
Hope this help.
PS: If you need to serialize the string, you can to use pascal string format so that you can support string with variable length. e.g. "11hello world", or "3foo".

Array without parameters in c++

I'm pretty new in c++ althought a bit experienced in java, and my problem it's the next one:
I'm doing a sudoku project where I'm creating an abstract data type of the box and the board. In the board one, I'm creating a bidimesional array of boxes, but when I want to create it as a public data so I can use it in the whole class and not only in the board constructor.
I'm creating it in the board constructor because If I don't create it there, I have no way of knowing the value of each dimension, and if I create the variable Box box[int][int] where I can use it in the class, I've got no way of knowing the dimensions. It'll be better understandable with some code.
This code allows me to create the Box array with the dimensions I want, because it's in the board constructor than when it's created it has as a parameters the number of boxes, but it don't let me use the "casilla" variable in the other part of the class nor other classes:
class tablero{
int filas;
int columnas;
public:
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
Casilla casilla[filas][columnas];
}
Casilla getCasilla(int n, int m){
return casilla[n][m]; <- Here shows an error because casilla cannot be resolved.
}
And this other code lets me use the casilla variable, but I have to give it the parameters to the dimensions before I know them:
class tablero{
int filas;
int columnas;
public:
Casilla casilla[0][0];
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
}
Casilla getCasilla(int n, int m){
return casilla[n][m];
}
No error, but the dimensions of the casilla array have to be given before I know them, and so, they may be the wrong ones (because the board may have different dimensions.
It's the first time I'm programming in c++, and I'm really frustated with this problem, can anyone help me to find a way to make it so it works both ways? (I already tried to leave both dimensions empty and then in the constructor put casilla[][] = Casilla cas[filas] [columnas] but it gives me an error..)
Thanks for the help everyone. Also, If you think the title is not clear enough, you can suggest one and I'll change it.
The Casilla code is this one:
class Casilla{
int fila;
int columna;
int numero;
public:
// constructor
Casilla(int fila, int columna,int numero)
{
this->fila = fila;
this->columna = columna;
this->numero = numero;
}
};
Thanks everyone for your answers, I've already found the answer I needed from 3 different people. I can't upvote all of you because I still don't have 15 reputation, but when I have it i'll upvote you all. Thanks for all your answers, really. I just need to know what I commented on the checked answer and it'll be all answered.
A solution with an array
//----------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
//----------------------------------------------------------------------------
class Casilla
{
int fila;
int columna;
int numero;
public:
// default constructor
Casilla()
{
this->fila = -1;
this->columna = -1;
this->numero = 0;
}
int GetNumero() {return numero;}
void SetCasilla (int _fila, int _columna) //set a cell position
{
fila = _fila;
columna = _columna;
}
void SetCasilla (int _numero) //set a cell value
{
numero = _numero;
}
void SetCasilla (int _fila, int _columna, int _numero) //set a cell position and value
{
fila = _fila;
columna = _columna;
numero = _numero;
}
};
class Tablero
{
int filas;
int columnas;
Casilla **casilla;
public:
Tablero (int filas, int columnas)
{
this->filas = filas;
this->columnas =columnas;
casilla = new Casilla* [filas];
for (int i = 0; i<filas; i++)
casilla[i] = new Casilla [columnas];
for (int i = 0; i<filas; i++)
for (int j = 0; j<columnas; j++)
casilla[i][j].SetCasilla(i,j); //set the right position for each cell
//the values = 0 by default
}
//destructor
~Tablero()
{
for (int i = 0; i<filas; i++)
delete [] casilla[i];
delete [] casilla;
}
//set a cell value in the table
void ChangeCasillaValue (int _fila, int _columna, int _numero)
{
casilla[_fila][_columna].SetCasilla (_numero);
}
Casilla getCasilla(int n, int m)
{
return casilla[n][m];
}
void PrintTablero ()
{
for (int i = 0; i<filas; i++)
{
for (int j = 0; j<columnas; j++)
std::cout << std::setw(5)<<casilla[i][j].GetNumero();
std::cout << "\n";
}
std::cout << "\n";
}
};
//----------------------------------------------------------------------------
int main()
{
int N = 5, M = 6;
Tablero table(N, M);
table.PrintTablero();
table.ChangeCasillaValue(1,1,-5); //change value in cell(1,1)
table.PrintTablero();
std::cin.get();
return 0;
}
//-----------------------------------------------------------------------------
You have to add a bunch of setters and getters of your own.
But, as a draft, it works.
C-style array dimensions must be known at compile-time in C++. So there is no variant of Casilla casilla[filas][columnas]; that will work.
Instead you should use a container which can hold the data you want to put in it. Use of C-style arrays in C++ is discouraged because they have some strange behaviour and rules, they are mainly there for backwards compatibility.
The simplest option is a 1-dimensional array with runtime size, that is called vector:
class tablero{
int filas;
int columnas;
std::vector<Casilla> casilla;
public:
tablero (int filas, int columnas)
: filas(filas), columnas(columnas), casilla(filas * columnas)
{ }
Casilla getCasilla(int f, int c) const
{
return casilla[f * columnas + c];
}
};
Note the use of the constructor initializer list. You should provide initial values for class members this way, instead of using assignment statements inside the constructor.
In your first example, in your constructor, the line
Casilla casilla[filas][columnas];
declares casilla an array of arrays of Casilla objects local to your constructor. Once your constructor returns, casilla goes out of scope. There is no casilla member variable or local variable in your getCasilla function, so of course it cannot be resolved.
In your second example, your class has a public member casilla declared as 0 by 0 array of Casilla objects. Your getCasilla function would return the item in the nth row and mth column of the 0 by 0 array. In C++, there is no bound checking on array dereferences, so this is returning some out of bounds memory location and is very bad.
You can create dynamic C arrays yourself by using malloc and free, but since you are using C++ it will be easier to just use std::vector.
For example, you could use:
#include <iostream>
#include <vector>
class Casilla
{};
class tablero
{
int filas_;
int columnas_;
std::vector<std::vector<Casilla> > casilla_; // a vector of vectors of Casillas
public:
tablero(int filas, int columnas) : filas_(filas), columnas_(columnas),
casilla_(filas, std::vector<Casilla>(columnas))
// The above is an initialization list
// We initialize casilla_ as a vector of filas vectors of columnas Casillas
{}
std::vector<std::vector<Casilla> > getCasilla() const
{
return casilla_;
}
};
int main(int argc, const char* argv[])
{
tablero t(3, 3);
std::cout << "casilla rows: " << t.getCasilla().size() << std::endl;
std::cout << "casilla cols: " << t.getCasilla()[0].size() << std::endl;
return 0;
}
First Casilla casilla[filas][columnas]; needs to be a class variable so it's accessible to all methods.
Second the sizes of rows and columns must be a fixed number e.g Casilla casilla[9][9];
If it need to be dynamically allocated you could you Vectors or Vectors of Vectors.
If it's 2d array, you can still create it as 1d array, but depends which is best for your purposes.

C++ Struct defined data passing. Simple answer im sure

I am sure this is a very simple fix and I feel dumb asking it but here it goes.
I need help with a struct and passing info from a gather function to a save or set function, and then passing it again to another function for further use.
Basically, it looks like this to start. I'll just add short snips of the code. All can be provided if you would like to see it.
I right now am just looking for the proper way to pass struct defined data from get.... to set.... functions.
struct printype
{
char dots[8][15];
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
};
int getunknown15(); // prototypes
int setunknown15(int);
then we have a simple main.
int main()
{
printype pt;
pt.unknown15=getunknown15();
pt.unknown15=setunknown15(12);
pt.serial11_14=getserial11_14();
pt.serial11_14=setserial11_14("12345678");
pt.year8=getyear8();
pt.year8=setyear8(44);
pt.month7=getmonth7();
pt.month7=setmonth7(11);
pt.day6=getday6();
pt.day6=setday6(12);
pt.hour5=gethour5();
pt.hour5=sethour5(12);
pt.minute2=getminute2();
pt.minute2=setminute2(23);
cout <<"-----------------------------------------------------"<<endl;
cout <<" Let's Get Started"<<endl;
cout <<"-----------------------------------------------------"<<endl;
setup(pt.dots); // sets up the array
dpinfo(pt); // prints out the final array
ftarray(pt);
spar(pt.dots);
darray(pt.dots);
}
and finally the get and set array functions.
int getunknown15()
{
printype tem;
cout <<"-----------------------------------------------------"<<endl;
cout <<" Enter the Unkown Variable (0-127): ";
cin >>tem.unknown15;
cout <<"-----------------------------------------------------"<<endl;
return tem.unknown15;
}
next is
int setunknown15(int tem)
{
printype pp;
if (tem>127||tem<0)
{
cout << "Error" << endl;
return 0;
}
else
{
pp.unknown15 = tem;
return pp.unknown15;
}
}
I hope this isn't too much to read and understand
Anyway, I know this has a really simple answer but my brain just isn't working right now.
Edit: As StilesCrisis stated, Send struct as parameter is quiet stupid in this case. better use a const reference.
Well, I am not sure if I understand your question correctly. You can simply send struct to another function as parameter, or as a pointer.
like:
void SetStruct(const printype& var);
printype GetStruct();
Is it what you are looking for?
Please use the following access to the your fields, (by reference):
struct printype *myPtr = new printype;
myPtr->day6 = 43;
When use pointer instead of a normal variable, you should use -> instead . to access your fields.
I know this is kind of old but I thought I should give it a shot, since you are using C++ and it looks like you are trying to use some OO practices (I think), you don't need to start with a struct, even though OO principles can be applied using them as well though not as elegantly.
you can define your class header file as such.
#ifndef PRINTYPE_H
#define PRINTYPE_H
#include <string>
using namespace std;
class printype
{
private: // we always want to declare our member fields private for safety/managements reasons, no one will be able to access them outside.
char dots[8][15];
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
void init(); // This is the method we use to initialize our starting state.
public: // This is our public methods, how people deal with/get/set our state.
printype(); // This is our default constructor
printype(const printype& print_type); // This our copy constructor
virtual ~printype(); // This is our destructor, its virtual, making safer for inheritance.
// This is our setters/getters
void setUnknown(int unknown);
int getUnknown();
void setYear(int year);
int getYear();
void setMonth(int mont);
int getMonth();
// and well you get the idea, you can add more methods.
};
#endif
and the accompanying class source file with your functions implementation
printype::printype()
{
this->init(); // Initialize all your vatiables, safer to just define a function to this.
}
printype::printype(const printype& orig) // copy constructor
{
this->setUknown(orig.getUnknown());
this->setDay(orig.getDay());
this->setDots(orig.getDots());
// you get the idea ...
}
printype::~printype()
{
// Have anything you need to do before destroying the object.
}
void printype::init()
{
this->setUnknwon(0);
this->setyear(0);
this->setMonth(1);
char dots[8][15] = {'\0'};
this->setDots(dots);
// you get the idea, you want to initialize all your variables since, for the most part they initially hold garbage.
}
void printype::setUnknown(int unknown)
{
if (unknown >= 0 && unknown < 127)
this->unknown15 = unknown;
else
error("Expecting unknown to be between 0 and 127"); // error should probably print the error and/or exit(-1) up to u
}
int printype::setYear(int year)
{
if (year >= 1 && year <= 99)
this->year8 = year;
else
error("Expecting year between 0 and 99"); // you may want to implement an error function!
}
int printype::getYear()
{
return this->year8;
}
void printype::setDots(char dots[8][15])
{
// you may want to do some verifications
memcpy(this->dots, dots, sizeof(dots));
}
void printype::setDots(char **dots) // this is a bit unsafe, use at your own risk.
{
if (dots)
{
unsigned int index = 0;
for (index = 0; index < 8; index++)
if (dots[index])
memcpy(this->dots[index], dots[index], 15);
else
error("dots required pointer ...");
}
else
error("dots required pointer ...");
}
char **getDots() // We will be returning a copy, we don't want the internal state to be affected, from outside, by using reference or pointers.
{
char **dots = new char*[8];
unsigned int index = 0;
for (index = 0; index < 8; index++)
{
dots[index] = new char[15];
memcpy(dots[index], this->dots[index], 15);
}
return dots;
}
// and well you get the idea ...
to use your class
printype *print_type_p = new print_type();
// or
printype pront_type_p();
// use the different public method to update the internal state.
print_type_p->setYear(3);
// or
print_type.setYear(3);
print_type_p->getYear();
// and so on.