How to write Console terminal with C++ [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am studying for an exam and need your help.
I must write my own console terminal in C++, which must work in this way:
Example:
:>plus 5 7 "hit ENTER"
:>12
:>minus 10 12 "hit ENTER"
:>-2
:>combine Hello World "hit ENTER"
:>HelloWorld
:>run netstat "hit ENTER"
:>runs netstat
:>help
:>plus int1 int2
minus int1 int2
combine string1 string2
run ?????
:>exit
program exits
For main block I think it would be something like this
int main(void) {
string x;
while (true) {
getline(cin, x);
detect_command(x);
}
return 0;
}
The functions would be something like this
void my_plus(int a, int b) {
cout << a + b;
}
void my_minus(int a, int b) {
cout << a - b;
}
void my_combine(string a, string b) {
?????????????;
}
void my_run(?????????) {
???????????;
}
And the finally detect_command
void detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0) {
?????????????????????;
}
}
}
????? - means I don`t know what to write.
Help to make this program work.
Thanks.

I'm going to use the minus operation as an example...
Make a structure like so:
struct cmd_struct {
const char *name;
void (*func) (void *data);
};
Since your function parameters aren't the same, you gotta make a structure for each, e.g.:
struct minus_op {
int rhs;
int lhs;
};
And use the cmd_struct as an array, like so:
static cmd_struct commands[] = {
{ "minus", &my_minus },
...
};
my_minus would then be:
void my_minus(void *data) {
struct minus_op *mop = data;
... do the computation and return ...
}
And loop through it to detect the command used:
for (int i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) {
if (strcmp(commands[i].name, a) == 0) {
... prepare the data ...
commands[i].func(data);
}
}
Side Note: In order to get the function parameters from command line, have a splitter, e.g. a white space. Use a vector for this and pass that vector to detect_command
Do also note: Get rid of the void param used in this example and use a char **argv and int argc like in main(). argv would be the arguments, and argc would be the number of arguments passed to the function. e.g. if you say to the program:
>> minus 5 1
Then argc should be 2 (the 5 and the 1) and argv[0] = "5" and argv[1] = "1".
Now that you know the idea behind it, implementing a more flexible version is left to you.

Call a respective function to handle each word. For example:
enum commands {
PLUS,
MINUS,
HELP,
EXIT
//....
};
int detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0)
return i;
}
return -1; //unknow word
}
Give the string to detect_command() the function return the respective integer to enum commands (that's our i value) or -1 if word is unknow. Then you can write a function like this to use and process the value determined by detect_command():
void run_command(int cmd)
{
switch(cmd) {
case PLUS: run_plus(); break;
case MINUS: run_minus(); break;
// and so on to all comamnds available
default: error("unknow command");
}
}
each function run_*() should continues the command parsing according to own rules, i.e, the "plus" command should be follow by one integer, one white-space and then another integer, right? run_plus() must validate it and then compute the result. e.g.:
//pseudo code
void run_plus()
{
//input here is one after "plus" word
//here we must validate our valid input: two digits split by a white-spaces
int x = parse_digit();
check(white-space);
int y = parse_digit();
int r = x + y;
display_result(r);
}
NOTE: I'm not a C++ programmer; I did detect_command() code modification to you get my idea. I even don't know if it will compile in C++ for the mismatch types.

Related

c++ Problem sorting struct array, probably issue with pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I am learning c++. I got a struct array that has an attribute that is also a struct.
typedef struct Date
{
int day, month, year;
}Date;
typedef struct {
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
char problem[50];
string technician_name;
char tech_fix[500];
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
}tech_info;
The question is that I need to sort it via date, that is the second attribute on tech_info.
Here is my attempt:
bool compare_date(const tech_info *a, const tech_info *b)
{
if (a->order_day.year < b->order_day.year)
return true;
if (a->order_day.year == b->order_day.year &&
a->order_day.month < b->order_day.month)
return true;
if (a->order_day.year == b->order_day.year &&
a->order_day.month == b->order_day.month &&
a->order_day.day < b->order_day.day)
return true;
// If none of the above cases satisfy, return false
return false;
}
static void sort_date(tech_info* all_orders[]) {
sort(all_orders, all_orders + counter, compare_date);
cout << "Sorted by date. " << "\n";
}
In this case counter is the amount of entries the user has submitted.
I submit two entries. For the first one I read the information correctly, but for the second one I don't. I'll attach two screenshots to show. Where is my mistake?
Update: Given that I am accessing bad memory I'll post a bit more of my code, all the parts that have to do with this logic.
Here is where I declare my array:
print_menu_initial();
int user_input;
cin >> user_input;
tech_info* orders[100]; //Empty by default
switch (user_input) {
case 1:
do_work_technician_mode(orders);
break;
case 2:
do_work_customer_mode(orders);
break;
}
Then the user does some operations to add orders from here:
static void do_work_customer_mode(tech_info* all_orders[]) {
while (true) {
cin >> user_input;
switch (user_input) {
case 0:
do_work_technician_mode(all_orders);
break;
case 1:
order[counter] = add_order();
all_orders[counter] = &order[counter];
counter++;
break;
case 2:
cout << "How many orders would you like to add? ";
cin >> many_orders;
for (int i = 0; i < many_orders; i++) {
cout << "Information for next order: " << "\n";
order[counter + i] = add_order();
all_orders[counter + 1] = &order[counter + 1];
}
counter = counter + many_orders;
break;
case 6:
sort_date(all_orders);
break;
}
The other cases are irrelevant, I believe. This is the sorting part. Counter is an int variable, declared 0 at start. Whenever the customer adds new entries I increase the value of counter with the number of entries he adds.
Funny enough - for my screenshot - variable a gets read correctly, just b is not being read correctly.
It appears that you have come to C++ from a C background. That is not a bad thing, but I would recommend learning to use as much of the standard library as you can. C++20 in particular has added many features that make it easier to work with collections of objects. This requires a (somewhat) up to date compiler, but is definitely worth it. Here is how I would prefer to approach a problem like this in C++.
There are two choices: keeping the collection of orders sorted at all times, or sorting only when needed. The former can be achieved using an ordered container such as std::set, the latter is what you are currently doing using std::sort. However, you could make your life a lot easier by storing the orders in a container like std::vector. Adding a new order is then as simple as
orders.emplace_back(add_order());
Tracking the number of orders in a counter variable is not necessary, since the vector has a size() function.
Further, if there is a natural choice of ordering among values of a type, as is the case with dates, then the recommendation in C++ is to overload comparison operators. This allows for uniform expression syntax like a != b and x < y when this makes sense for your class. By carefully ordering the members of your Date struct, this can be achieved with almost no code in modern C++:
#include <compare>
struct Date {
int year, month, day;
friend auto operator<=>(Date const&, Date const&) = default;
};
static_assert(Date{2000, 1, 1} < Date{2000, 1, 2});
A more sophisticated approach would also prohibit the construction of invalid dates. Classes designed this way were introduced to the std::chrono namespace with C++20; you should now be able to use a class like year_month_day that provides what you need out of the box.
Either way, C++20's range-based std::ranges::sort algorithm then allows you to specify both a comparison and a projection function; the projected values are compared to determine the sorting order. Therefore, once you have a date class with comparison operators, you can also sort the orders like this:
#include <algorithm>
auto order_date = [](auto const& order) -> auto& { return order.order_date; };
std::ranges::sort(orders, std::ranges::less{}, order_date);
The answer to your problem was a type in all_orders[counter + i] = &order[counter + i];
But since we're here let me clean your code up a bit. I can see you've most likely come from C as most of your syntax is C like. So here are some rules (some may be controvertial but wtvr
typedef struct Date //for structs -> struct NAME. typedef not needed
{
int day, month, year;
}Date; //you're declaring globabl object which isnt that good you want to have as little variables globally
typedef struct { //same here
int order_num; //struct has a lot of variables, i assume all of them are needed
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
char problem[50]; //if this can have many sizes better use string
string technician_name;
char tech_fix[500]; //same here. string. you can always change string to char using function someStringName.c_str() other way round is also possible with minimal effort
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
}tech_info; //same here
What you'd prefer to see in a cpp program is the following:
struct Date
{
int day, month, year;
};
struct tech_info{
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
string problem;
string technician_name;
string tech_fix;
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
faults problems[10];
};
And then your actual objects created in eg main function or some other function.
Next your sorting:
bool compare_date(const tech_info &a, const tech_info &b) //pointers to references
{
if (a.order_day.year < b.order_day.year) //id do it similar but a bit differently
return true;
if (a.order_day.year == b.order_day.year &&
a.order_day.month < b.order_day.month)
return true;
if (a.order_day.year == b.order_day.year &&
a.order_day.month == b.order_day.month &&
a.order_day.day < b.order_day.day)
return true;
// If none of the above cases satisfy, return false
return false;
}
static void sort_date(tech_info* all_orders[]) { //here you have double pointer *name[]. [] also acts as * so you have **all_orders
sort(all_orders, all_orders + counter, compare_date); //sort, assuming its sort() from #include <algorithms> uses i think single pointer to beginning of array, end array then type of sorting
cout << "Sorted by date. " << "\n"; //endl instead of "\n"
}
I'd do it like this:
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
struct Date
{
int day, month, year;
Date(int d, int m, int y) : day(d), month(m), year(y) {}
Date() {}
};
struct tech_info{
int order_num;
Date order_day; //Sort
string client;
string tech_type;
int serial_key;
string problem;
string technician_name;
string tech_fix;
int price;
int days_spent;
string status;
string order_type;
string urgency;
int problems_num;
//faults problems[10]; you didnt define what this faults structure was
//making contructor for this class would be perfect
tech_info(int orderNum, int dateDay, int dateMonth, int dateYear, string cl, string techType, int serial, ...)
: order_num(orderNum), Date(dateDay, dateMonth, dateYear), client(cl), tech_type(techType), serial_key(serial), ... {}
tech_info() {}
};
bool compare_date(const tech_info &a, const tech_info &b) //pointers to references
{
if (a.order_day.year == b.order_day.year) //if year is the same
{
if (a.order_day.month == b.order_day.month) //if month is same
{
if (a.order_day.day < b.order_day.day) return true; //if day is different
else return false;
}
else //if month is different
{
if (a.order_day.month < b.order_day.month) return true;
else return false;
}
}
else //if year is different
{
if (a.order_day.year < b.order_day.year) return true;
else return false;
}
}
void sort_date(vector<tech_info> &all_orders) { //i suggest all your tech_info put into vector + no static function
sort(all_orders.begin(), all_orders.end(), compare_date);
cout << "Sorted by date." << endl;
}
int main()
{
vector<tech_info> techInfo;
//to add:
techInfo.emplace_back(tech_info(1,2,3,4,"client","sometech", 1234));
//to remove:
techInfo.erase(techInfo.begin() + 0); //where 0 is the index of the item you want to delete from vector
sort_date(techInfo);
}
Hope this helps!!!

bool vs void vs print or std::cout [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
What is the difference between having a void or a bool and why is the answer not displaying right? The more I look up and try to understand the deeper I dig myself into a whole. (eg: std::boolalpha)?!?
#include <iostream>
#include <stdio.h>
#include <vector>
bool findPair(int* arr, int arrLength, int k)
{
for(int i=0; i<arrLength; i++)
{
for(int j = i+1;j<arrLength; j++)
{
if(arr[i] + arr[j] == k)
{
printf("Pair Found (%d, %d)", arr[i], arr[j], "\n");
//return;
}
}
}
printf("Pair NOT Found!");
//return false;
}
int main()
{
int array[5] = {4,5,1,7,2};
int sum = 221;
int arrLength = sizeof(array)/sizeof(array[0]);
findPair(array, arrLength, sum);
std::cout << std::endl << findPair() << std::endl;
// return 0;
}
Gives the following output when a pair is found (int sum = 3;):
Pair Found (1, 2)Pair NOT Found!
1
And this output when the pair is not found (int sum = 221;):
Pair NOT Found!
1
Right now, you've told the compiler that findPair returns a bool, but the method doesn't actually return true or false. You've lied to the compiler, and the compiler is allowed to do whatever it wants in this case. A function with a return type should always have a return statement that tells the compiler what value to return to the caller (or throw an exception).
A method with a void return type does not have to have a return; statement, and it's return; statements do not have to return a value, but you can still use return; statements to tell the computer to stop executing the method and return to the caller.
In your case, since you've eliminated the return statement after "Pair Found (%d, %d)", the method keeps executing, until it reaches the end of the loop, which is why you see both printf statements execute. Make sure to put a return type there.
Separately, std::cout << findPair will try print the address of the function, but since there's no overload for that, it will convert the pointer to a boolean, thus printing 1. What you probably wanted was to store the returned value into a bool variable, and send that to cout?
If you want to output true or false instead of 1 or 0 for bool types, then stream out std::boolalpha first, as in std::cout << std::boolalpha << myBoolean;

Create big numbers by BCD - C++

I want to create code that will help me get numbers bigger than MAXINT. I heard about that I can use Binary Code Decimal to do this, and then every two of decimal numbers(converted to BCD) of the bigger number keep in char. But how to do this? I should give string as input, then convert somehow to BCD every single decimal number? And how can I put two converted decimal numbers to one char? I'm new in C++ and don't know how can i do it.
P.S. I don't want to use libraries which are "special" for that kind of problems.
As it turns out, this is actually quite simple. How about we try to take it to the next level?
Below is an implementation of a BCD number with infinite(or as much as memory can hold) size. It only supports positive integer numbers. I'll leave extending this to support negative numbers(or real numbers) as an exercise.
First things first: Yes, we want to get our number as a string and then build it up from that. Since it's only an integer, this is actually quite easy to do. We primarily create a helper function to aid us in identifying all the digits.
int char_to_int(const char c) {
int ret = c - '0';
if(ret > 9 || ret < 0) throw 1; // for simplicity. Use a class derived from std::exception instead.
return ret;
}
We can now try to implement input and output for our big number.
First Try
Having that helper guy, turning a string to a BCD-encoded buffer is easy. A common implementation may look like this:
int main() {
unsigned char bignum[10]; // stores at most 20 BCD digits.
std::memset(bignum, 0, sizeof(bignum));
std::string input;
std::cin >> input;
try {
if (input.size() > 20) throw 1; // Avoid problems with buffer overflow.
for (int i=1;i<=input.size();i++) {
int n = char_to_int(input[input.size()-i]);
bignum[sizeof(bignum) - (i+1)/2] |= n << (i%2)*4; // These are bitwise operations. Google them!
}
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
return 0; // Exit cleanly.
}
// bignum is now filled. Let's print it to prove.
for (int i=0;i<sizeof(bignum);i++) {
int first_digit = bignum[i] & '\x0F'; // Right side, doesn't need to shift.
int second_digit = (bignum[i] & '\xF0')>>4; // Left side, shifted.
std::cout << first_digit << second_digit;
}
}
This is not very space-efficient, however. Note that we have to store all the 20 digits, even if our number is small! What if we needed 1000 digits? What if we need 1000 numbers that may or may not have these 1000 digits? It is also error-prone: Look that we had to remmember to initialize the array, and do a bounds check before conversion to avoid a buffer overflow.
Second Try
We can improve our implementation using a std::vector:
int main() {
std::vector<unsigned char> bignum; // stores any quantity of digits.
std::string input;
std::cin >> input;
try {
// For an odd number of digits we want a trailling zero at the end.
if(input.size()%2) n.num_vec.push_back(char_to_int(input[0]));
for (unsigned i=input.size()%2;i<input.size();i+=2) {
int left = char_to_int(input[i]);
int right = char_to_int(input[i+1]);
n.num_vec.push_back(0);
n.num_vec.back() = left << 4;
n.num_vec.back() |= right;
}
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
exit(0); // Exit cleanly.
}
// bignum is now filled. Let's print it to prove.
for (unsigned i=0;i<bignum.size();++i) {
// Notice that we inverted this from the previous one! Try to think why.
int first_digit = (bignum[i] & '\xF0')>>4; // Left side, shifted.
int second_digit = bignum[i] & '\x0F'; // Right side, doesn't need to shift.
if(i || first_digit) std::cout << first_digit; // avoid printing trailling 0.
std::cout << second_digit;
}
}
Lookin' good, but that is too cumbersome. Ideally, the bignumber user shouldn't have to deal with the vector positions and all that mumbo-jumbo. We want to write code that behaves like:
int main() {
int a;
cin >> a;
cout << a;
}
And it should just work.
Third Try
Turns out this is possible! Just wrap bignum into a class, with some helpful operators:
class bignum {
std::vector<unsigned char> num_vec;
template<typename T>
friend T& operator<<(T& is, bignum& n);
template<typename T>
friend T& operator>>(T& os, bignum& n);
};
// Get input from any object that behaves like an std::istream (i.e.: std::cin)
template<typename T>
T& operator>>(T& is, bignum& n) {
std::string input;
is >> input;
n.num_vec.reserve(input.size());
if(input.size()%2) n.num_vec.push_back(char_to_int(input[0]));
for (unsigned i=input.size()%2;i<input.size();i+=2) {
int left = char_to_int(input[i]);
int right = (i+1) != input.size()?char_to_int(input[i+1]):0; // If odd number of digits, avoid getting garbage.
n.num_vec.push_back(0);
n.num_vec.back() = left << 4;
n.num_vec.back() |= right;
}
return is;
}
// Output to any object that behaves like an std::ostream (i.e.: std::cout)
template<typename T>
T& operator<<(T& os, bignum& n) {
for (unsigned i=0;i<n.num_vec.size();++i) {
int first_digit = (n.num_vec[i] & '\xF0')>>4; // Left side, shifted.
int second_digit = n.num_vec[i] & '\x0F'; // Right side, doesn't need to shift.
if(i || first_digit) os << first_digit; // avoid printing trailling 0.
os << second_digit;
}
return os;
}
Then our main function looks much more readable:
int main() {
bignum a;
try {
std::cin >> a;
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
return 0; // Exit cleanly.
}
std::cout << a;
}
Epilogue
And here we have it. Of course with no addition, multiplication, etc. operators, it isn't very useful. I'll leave them as an exercise. Code, code and code some more, and soon this will look like a piece of cake to you.
Please feel free to ask any questions. Good coding!

All possible combinations(with repetition) as values in array using recursion

I'm trying to solve a problem in which I need to insert math operations(+/- in this case) between digits or merge them to get a requested number.
For ex.: 123456789 => 123+4-5+6-7+8-9 = 120
My concept is basically generating different combinations of operation codes in array and calculating the expression until it equals some number.
The problem is I can't think of a way to generate every possible combination of math operations using recursion.
Here's the code:
#include <iostream>
#include <algorithm>
using namespace std;
enum {noop,opplus,opminus};//opcodes: 0,1,2
int applyOp(int opcode,int x, int y);
int calculate(int *digits,int *opcodes, int length);
void nextCombination();
int main()
{
int digits[9] = {1,2,3,4,5,6,7,8,9};
int wantedNumber = 100;
int length = sizeof(digits)/sizeof(digits[0]);
int opcodes[length-1];//math symbols
fill_n(opcodes,length-1,0);//init
while(calculate(digits,opcodes,length) != wantedNumber)
{
//recursive combination function here
}
return 0;
}
int applyOp(int opcode,int x, int y)
{
int result = x;
switch(opcode)
{
case noop://merge 2 digits together
result = x*10 + y;
break;
case opminus:
result -= y;
break;
case opplus:
default:
result += y;
break;
}
return result;
}
int calculate(int *digits,int *opcodes, int length)
{
int result = digits[0];
for(int i = 0;i < length-1; ++i)//elem count
{
result = applyOp(opcodes[i],result,digits[i+1]);//left to right, no priority
}
return result;
}
The key is backtracking. Each level of recursion handles
a single digit; in addition, you'll want to stop the recursion
one you've finished.
The simplest way to do this is to define a Solver class, which
keeps track of the global information, like the generated string
so far and the running total, and make the recursive function
a member. Basically something like:
class Solver
{
std::string const input;
int const target;
std::string solution;
int total;
bool isSolved;
void doSolve( std::string::const_iterator pos );
public:
Solver( std::string const& input, int target )
: input( input )
, target( target )
{
}
std::string solve()
{
total = 0;
isSolved = false;
doSolve( input.begin() );
return isSolved
? solution
: "no solution found";
}
};
In doSolve, you'll have to first check whether you've finished
(pos == input.end()): if so, set isSolved = total == target
and return immediately; otherwise, try the three possibilities,
(total = 10 * total + toDigit(*pos), total += toDigit(*pos),
and total -= toDigit(*pos)), each time saving the original
total and solution, adding the necessary text to
solution, and calling doSolve with the incremented pos.
On returning from the recursive call, if ! isSolved, restore
the previous values of total and solution, and try the next
possibility. Return as soon as you see isSolved, or when all
three possibilities have been solved.

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.