Anonymous struct not inside named type - c++

I have trouble with DES algorithm. How to solve this?
(I'm using DevC++ v5.11)
I don't completely understand what DES are. What should I do/try ?
// Triple DES (3DES)
void DES::inital_key(const char key[64],char ekey[16][48],bool is_crypt)
{
union{ //Error here
char pkey[56];
struct{char l[28],r[28];};
};
permute(key,pkey,_DES::perm1,56);
for(uint n=0; n<16; n++) {
lshift(l,_DES::sc[n]);
lshift(r,_DES::sc[n]);
permute(pkey,ekey[is_crypt?n:15-n],_DES::perm2,48);
}
}
/////////////////////////////////////////////////////////////////////////////
void DES::work(const char in[64],char out[64],const char key[64],bool is_crypt)
{
char ekey[16][48];
union{ //And here
char pin[64];
struct{char l[32],r[32];};
};
inital_key(key,ekey,is_crypt);
permute(in,pin,_DES::perm3,64);
for(uint n=0; n<16;) round(l,r,ekey[n++]),round(r,l,ekey[n++]);
permute(pin,out,_DES::perm6,64);
}

You are declaring anonymous structs inside of unnamed unions, just like the compiler errors say. You need to assign names to the unions (and for portability, you should name the structs, too):
void DES::inital_key(const char key[64], char ekey[16][48], bool is_crypt)
{
union {
char pkey[56];
struct { char l[28], r[28]; } s;
} u;
permute(key, u.pkey, _DES::perm1, 56);
for(uint n = 0; n < 16; n++) {
lshift(u.s.l, _DES::sc[n]);
lshift(u.s.r, _DES::sc[n]);
permute(u.pkey, ekey[is_crypt ? n : 15-n], _DES::perm2, 48);
}
}
void DES::work(const char in[64], char out[64], const char key[64], bool is_crypt)
{
char ekey[16][48];
union {
char pin[64];
struct { char l[32], r[32]; } s;
} u;
inital_key(key, ekey, is_crypt);
permute(in, u.pin, _DES::perm3, 64);
for(uint n = 0; n < 16;) round(u.s.l, u.s.r, ekey[n++]), round(u.s.r, u.s.l, ekey[n++]);
permute(u.pin, out, _DES::perm6, 64);
}

This code is relying on a Microsoft extension.
Your compiler, GCC, does not understand it.
You cannot use this code unless you make it standard C++, or switch compilers.

Related

how to pass and retrieve char array in c++

I am trying to pass a character array to a function. Set the values onto a character array. Then retrieve it and print using another function. But not able to get the result. Here is the code
class cSummary{
private:
char *cSummaryTable[2];
public:
void printSummary();
void setSummary(char *ptr, int stage);
char *getSummary();
};
void cSummary::printSummary(){
char *cPtr = getSummary();
for(int i = 0; i < 2; i++){
cout << cPtr[i] << endl;
}
}
void cSummary::setSummary(char ptr[], int stage){
switch(stage){
case 0:
cSummaryTable[0] = ptr;
break;
case 1:
cSummaryTable[1] = ptr;
break;
}
}
char *cSummary::getSummary(){
return *cSummaryTable;
}
int main(int argc, char const *argv[])
{
cSummary summary;
summary.setSummary("first message!", 0);
summary.setSummary("second message!!", 1);
summary.printSummary();
return 0;
}
getSummary is the problem since it only returns the first string. Notice the assymmetry between getSummary and setSummary, setSummary has a stage parameter but there's no such parameter in getSummary. That should have been a clue that something was wrong. I would recode like this
char *cSummary::getSummary(int stage) {
return cSummaryTable[stage];
}
void cSummary::printSummary() {
for(int i = 0; i < 2; i++){
cout << getSummary(i) << endl;
}
}
And I'll add the obiligatory piece of good advice. You should learn to program modern C++, which doesn't use arrays and pointers, but uses the much safer and easier to understand std::string and std::vector instead.

passing an array of structs to a function and changing it through the fucntion

so this is my code but it wont compile for some reason.
Error 3 error C2036: 'pjs *' : unknown size
Error 4 error C2100: illegal indirection
Error 5 error C2037: left of 'size' specifies undefined struct/union 'pjs'
void initArray(struct pjs* array)
{
(*array[1]).size = 1;
}
struct pjs{
char* name;
int size;
int price;
};
int main(int argc , char** argv)
{
struct pjs array[10];
initArray(array);
system("PAUSE");
return (0);
}
Following may help:
struct pjs{
char* name;
int size;
int price;
};
// safer to use one of the following declaration
// void initArray(pjs *array, std::size_t size) // simpler
// void initArray(pjs (&array)[10]) // more restrictive but unintuitive syntax
void initArray(pjs* array)
{
array[1].size = 1;
}
int main()
{
pjs array[10];
initArray(array);
}
Definition of pjs should be given before to use it (or requiring its size).
array[1] is a pjs so *array[1] is illegal (as pjs no have operator*)
That simply should be
array[1].size = 1;
Correct your 1st statement of initArray to :
array[1].size = 1;
and cut paste the struct declaration to before the function.
If you want to initialize the entire array, you need to pass the array and a size to initArray.
int main(int argc , char** argv)
{
struct pjs array[10];
initArray(array, sizeof(array)/sizeof(array[0]));
system("PAUSE");
return (0);
}
and then, initialize each object the array as:
void initArray(struct pjs* array, size_t size)
{
for (size_t i = 0; i < size; ++i )
{
array[i].size = 1;
array[i].price = 0; // Or whatever makes sense
array[i].name = malloc(1); // Or whatever makes sense.
}
}

Array of structs declaration

I am trying to write this C++ function in which I am trying to set each Sequence in the array of Sequences, however when I follow the code on debug I notice that the array is not changing. In particular:
compressed.data[compressedDataCounter].c = pic.data[i];
compressed.data[compressedDataCounter].times = counter+1;
don't seem to add any new variables to the array, just override the first one.
I am thinking that the root of the problem is the declaration:
CompressedPic compressed;
compressed.data = new Sequence[pic.height * pic.width];
This is the portion of the code:
struct Sequence
{
char c;
int times;
};
struct CompressedPic
{
int height;
int width;
Sequence* data;
};
struct Picture
{
int height;
int width;
char* data;
};
CompressedPic compressThePicture(Picture pic) {
CompressedPic compressed;
compressed.data = new Sequence[pic.height * pic.width];
compressed.height = pic.height;
compressed.width = pic.width;
int compressedDataCounter=0;
for(int i=0; i<(pic.height * pic.width)-1; i++)
{
int counter = 0;
while(pic.data[i] == pic.data[i+1])
{
i++;
counter++;
}
compressed.data[compressedDataCounter].c = pic.data[i];
compressed.data[compressedDataCounter].times = counter+1;
compressedDataCounter++;
}
compressed.data[compressedDataCounter].times = -1;
return compressed;
}
It would be great if someone could figure out why this is happening.
You might want to change:
compressed.data[compressedDataCounter].c = counter+1;
to:
compressed.data[compressedDataCounter].times = counter+1;
So you can change the .times member otherwise you will be overriding your .c member. Right now you are setting .c to 'a' for example. Then you set .c to 103 (counter+1). Which is an int and likely with your archetecture the high bytes are aligning with .c and setting it to 0 as well.
So .c is getting 0'd and .times is never set

what does this mean char (*(*a[4])())[5]?

Hi I came across the question in "Test your skills in c++".
Please let me know what does it mean with an example?
Edited Section: Sorry for the extra parenthesis, edited & removed.
char (*(*a[4])())[5]
Following the spiral rule (as linked to by chris), and starting with the identifier:
a
...is...
a[4]
...an array of 4...
*a[4]
...pointers to...
(*a[4])()
...a function taking no parameters...
*(*a[4])()
...returning pointer to...
(*(*a[4])())[5]
...an array of five...
char (*(*a[4])())[5]
...chars.
Sidenote: Go give the architect who came up with this a good dressing-down, then find the programmer who wrote this code without a comment explaining it and give him a good dressing-down. In case this was given to you as a homework, tell your teacher that he should have instructed you on how to use cdecl instead, or how to design code in a way that it doesn't look like madman scrawlings, instead of wasting your time with this.
I cheated by removing what I think is an extra right-parenthesis and pasting the result into cdecl.
declare a as array 4 of pointer to function returning pointer to array 5 of char
And another example... of what to never ever do in anything other than an example.
#include <iostream>
typedef char stuff[5];
stuff stuffarray[4] = { "This", "Is", "Bad", "Code" };
stuff* funcThis() { return &(stuffarray[0]); }
stuff* funcIs() { return &(stuffarray[1]); }
stuff* funcBad() { return &(stuffarray[2]); }
stuff* funcCode() { return &(stuffarray[3]); }
int main()
{
char (*(*a[4])())[5] = { funcThis, funcIs, funcBad, funcCode };
for(int i = 0; i < 4; ++i)
{
std::cout << *a[i]() << std::endl;
}
return 0;
}
And here's an example ...
#include <stdio.h>
char a[5] = "abcd";
char b[5] = "bcde";
char c[5] = "cdef";
char d[5] = "defg";
char (*f1())[5] { return &a; }
char (*f2())[5] { return &b; }
char (*f3())[5] { return &c; }
char (*f4())[5] { return &d; }
int main()
{
char (*(*a[4])())[5] = { &f1, &f2, &f3, &f4 };
for (int i = 0; i < 4; i++)
printf("%s\n", *a[i]());
return 0;
}

Constructors and array of object in C++

I'm trying to create an application in C++. In the application I have the default constructor and another constructor with 3 arguments.
The user is providing from the keyboard an integer that it will be used to create an array of objects using the non default constructor.
Unfortunately I haven't been able to finish it till now, since I'm having issues with the creation of the array of objects that they will use the non default constructor.
Any suggestions or help?
#include<iostream>
#include<cstring>
#include<cstdlib>
#include <sstream>
using namespace std;
class Station{
public:
Station();
Station(int c, char *ad, float a[]);
~Station();
void setAddress(char * addr){
char* a;
a = (char *)(malloc(sizeof(addr+1)));
strcpy(a,addr);
this->address = a;
}
void setCode(int c){
code=c;
}
char getAddress(){
return *address;
}
int getCode(){
return code;
}
float getTotalAmount(){
float totalAmount=0;
for(int i=0;i<4;i++){
totalAmount+=amount[i];
}
return totalAmount;
}
void print(){
cout<<"Code:"<<code<<endl;
cout<<"Address:"<<address<<endl;
cout<<"Total Amount:"<<getTotalAmount()<<endl;
cout<<endl;
}
private:
int code;
char *address;
float amount[4];
};
Station::Station(){
code= 1;
setAddress("NO ADDRESS GIVEN");
amount[0]= 0.0;
amount[1]= 0.0;
amount[2]= 0.0;
amount[3]= 0.0;
}
Station::Station(int c, char *ad, float a[]){
if( (c>=1&& c<=10 ) ){
code=c;
address=ad;
for(int i=0;i<4;i++){
amount[i]=a[i];
}
}else{
code= 1;
setAddress("NO ADDRESS GIVEN");
amount[0]= 0.0;
amount[1]= 0.0;
amount[2]= 0.0;
amount[3]= 0.0;
}
}
Station::~Station(){
}
int main(){
int size,code;
char *addrr;
addrr = (char *)(malloc(sizeof(addrr+1)));
float mes[4];
do{
cout<<"size of array:";
cin>>size;
}while(size<=0 || size>=11);
// Station *stations= new Station[size];
// Station** stations = new Station*[size];
Station stations[size];
for(int i=0;i<size;i++){
cout<<"code:";
cin>>code;
cout<<"address:";
cin>>addrr;
double amo=0;
for(int k=0;k<4;k++){
cout<<"values"<<k+1<<":";
cin>>mes[k];
}
}
/*
for(int q=0;q<size;q++){
stations[q].print();
}
*/
return 0;
}
the values that I'll take from cin I want to assign them to the objects of the array!
You can either create the array default-initialized and then fill the array with the wanted object:
foo arr[10];
std::fill(arr, arr+10, foo(some, params));
Alternatively you could use std::vector and do just:
std::vector<foo> arr(10, foo(some, params));
In C++0x, you can use braced-init-list in new expression, which means you can do this:
#include <iostream>
class A
{
public:
A(int i, int j){std::cout<<i<<" "<<j<<'\n';}
};
int main(int argc, char ** argv)
{
int *n = new int[3]{1,2,3};
A *a = new A[3]{{1,2},{3,4},{5,6}};
delete[] a;
delete[] n;
return 0;
}
Compiled under g++ 4.5.2, using g++ -Wall -std=c++0x -pedantic
Since you say you can't use std::string, this is going to be much more difficult. The line addrr = (char *)(malloc(sizeof(addrr+1))); is not doing what you think it is. Instead of using malloc to allocate on the heap and since there is no free (which will lead to a memory leak), it will be much easier if we allocate on the stack with a predetermined buffer size: char addrr[BUFFER_LENGTH]. With BUFFER_LENGTH defined before Station's declaration as const int BUFFER_LENGTH = 20; or some other appropriate length.
To use the non-default constructor, adding stations[i] = Station(c, addrr, mes); at the end of the for loop will do the trick.
for(int i=0;i<size;i++){
cout<<"code:";
cin>>code;
cout<<"address:";
cin>>addrr; // do not read in strings longer than 20 characters or increase BUFFER_LENGTH’s size
double amo=0;
for(int k=0;k<4;k++){
cout<<"values"<<k+1<<":";
cin>>mes[k];
}
stations[i] = Station(c, addrr, mes);
}
But, this is not going to work properly since the constructor is copying the addrr pointer, not the data. I would recommend also changing the data member char *address to char address[BUFFER_LENGTH]. Then, in the constructor you can replace the line address=ad; with strcpy(address, ad);.
Note: setAddress and getAddress will now need to be updated.
Another line that is troubling is Station stations[size];. This is non-standard since size is not a known at compile time. Either use Station *stations= new Station[size]; and remember to delete or if you can use a std::vector, use std::vector<Station> stations(size);
If you do go the std::vector route, using push_back will work nicely:
std::vector<Station> stations;
for(int i=0;i<size;i++){
cout<<"code:";
cin>>code;
cout<<"address:";
cin>>addrr;
double amo=0;
for(int k=0;k<4;k++){
cout<<"values"<<k+1<<":";
cin>>mes[k];
}
stations.push_back( Station(c, addrr, mes) );
}