Sign in to follow this  
Poigahn

Need Code Translation From Pascal/Delph to C++

Recommended Posts

Poigahn    598

I am having trouble in accomplishing certain task in C++ which I am able to do in Pascal / Delphi quite easily.

1st

 In Pascal :  Type DataBase  record = Name:String(25); Cell:String(12); City:String(20); end;

                    Customer : DataBase;

 In C++:  class DataBase = {public: char Name[25], Cell[12], City[20];};

               DataBase Customer;

 

OKAY  we are good here.

 

  In Pascal :  Customer.Name = "Poigahn";

  In C++:       Customer.Name = "Poigahn";   < Will Not Compile 

So I am writing a segment of code that changes the information inside Variable Customer based on Conditions, So I do not want to assign values at time of instance.  Also do not want to use the cin function because values are predetermined by programmer.  So How do I do this ?

 

2cnd

 

  In Pascal :  With Customer do

                     Name = "Poigahn";

                     Cell = " 1234567890";

                     City = " Somewhere"; end; 

                      or

                     readln(Name);   I can make assignments this way ( useful when there is allot of info to change withinh the class variable )

  Rather Than Having to do assignments by doing > Customer.Name = "  "  or Readln(Customer.Name)

 

  In C++  :  I can not find any such function.  ( I might be looking right over it since I do not know what the function would be )

   Now I have to do cin >> Customer.Name;

  or

   getline(cin,Customer.Name);

 

Does anyone know how to do in C++  what I am able to do in Pascal  ??

Share this post


Link to post
Share on other sites
Rattrap    3385

For the first problem.

 

The problem is you can't just assign a char array ("Poigahn") to another char array (char Name[25]) like that.  You'd need to use a function like strcpy.  You'd be better off using std::string in place of a char array in the class.  It would allow an assignment like this.

 

[edit]

 

I think std::string will solve your second issue as well.

Edited by Rattrap

Share this post


Link to post
Share on other sites
Poigahn    598

The class will eventually be save to a binary file on the disk,  so do you not need a structured length that the char[25] gives you  versus the string which does not have a structured length ?

Share this post


Link to post
Share on other sites
Rattrap    3385

That depends on how you are serializing the class, which you don't show in your example.

 

You could prefix the string with its length in the file, allowing you to know how many characters are in the string.

 

Something else you might want to look at would be replacing public access to the variables with public getters and setters and making the member variables themselves private.  This would allow you to truncate the input string down to the desired number of characters, if that is what you wish.

Edited by Rattrap

Share this post


Link to post
Share on other sites
Barbossa    967

You can just use a custom function for saving the string to a file instead. I don't have a compiler here to check, but it can look like this:

void writeString( const std::ofstream &file, std::string str )
{
   file << str.size();
   file->write(str.c_str(), sizeof(char) * str.size());
}

Or something like that. Also, do you really need a class for your record? struct is also applicable (Shouldn't make a difference ;) )

 

EDIT: To slow... (full ten minutes)

Edited by Barbossa

Share this post


Link to post
Share on other sites
Poigahn    598


You'd need to use a function like strcpy

 

Is There any shorter Coding Than  strcpy(customer.name,"Jeremy Smith");

                                                        strcpy(customer.cell,"123456789");

 

I can intialize everything at time of instance, For the short Program than I am writing ( Testing some theories in a short test program )  in which depending upon user input, I would change these entries from 1 set of data to another then maybe back to the first.  All may not change, maybe just customer.cell ?

Share this post


Link to post
Share on other sites
Khatharr    8812

Is There any shorter Coding Than  strcpy(customer.name,"Jeremy Smith");

                                                        strcpy(customer.cell,"123456789");

 

-.-

If you want it simpler than that then use a std::string.

Also, when dealing with C-style strings, at least use a safe strcpy function so you don't overflow.

 

I can intialize everything at time of instance, For the short Program than I am writing ( Testing some theories in a short test program )  in which depending upon user input, I would change these entries from 1 set of data to another then maybe back to the first.  All may not change, maybe just customer.cell ?

 

Has anyone really been far even as decided to use even go want to do look more like?

Share this post


Link to post
Share on other sites
Ohforf sake    2052
how about (warning, untested):
template<unsigned maxLen>
struct __attribute__ ((packed, gcc_struct)) FixedString {
    uint8_t len;
    char buffer[maxLen];
    enum {
        MAX_LEN = maxLen
    };

    FixedString() { len = 0; }

    std::string toString() const {
        std::string str;
        unsigned l = std::min<size_t>(len, MAX_LEN);
        str.resize(l);
        memcpy(&str[0], buffer, l);
        return str;
    }
    void fromString(const std::string &str) {
        len = std::min<size_t>(str.length(), MAX_LEN);
        memcpy(buffer, str.c_str(), len);
    }
    void operator=(const std::string &str) { fromString(str); }
    void fromString(const char *str) {
        len = std::min<size_t>(strlen(str), MAX_LEN);
        memcpy(buffer, str, len);
    }
    void operator=(const char* str) { fromString(str); }
};
and then go
class DataBase {
    public: 
        FixedString<25> Name;
        FixedString<12> Cell;
        FixedString<20> City;
};
should be binary compatible with pascal string.

Edit: Boy, lot's of copy&paste errors... Edited by Ohforf sake

Share this post


Link to post
Share on other sites
Vortez    2714

If you don't want strcpy everywhere, just write a function for that.

void FillCustomer(char *pName, char *pCell, char *pCity)

{

    strncpy(customer.Name, pName, 25);

    strncpy(customer.City, pName, 12);

    strncpy(customer.Cell, pName, 20);

}

...

FillCustomer("Poigahn", "somewhere", "something");

And for text file io, you could use fputs and fgets.

FILE *f = fopen("MyFile.txt", "wt+");

if(f){

    fputs(customer.Name, f); fputs("\n", f);

    fputs(customer.City, f); fputs("\n", f);

    fputs(customer.Cell, f); fputs("\n", f);

    fclose(f);

}

then use fgets instead of fputs to retreive the data

FILE *f = fopen("MyFile.txt", "rt");

if(f){

    fgets(customer.Name, 25, f);

    fgets(customer.City, 12, f);

    fgets(customer.Cell, 20, f);

    fclose(f);

}

EDIT: just saw you wanted a binary format, it's even easier that way.

FILE *f = fopen("MyFile.txt", "wb+");

if(f){

    fwrite(&customer, 1, sizeof(customer), f);

    fclose(f);

}

...

FILE *f = fopen("MyFile.txt", "rb");

if(f){

    fread(&customer, 1, sizeof(customer), f);

    fclose(f);

}

As for the second question, i never really used or liked this trick in delphi, and i think it's pretty unique to the language. One way to do something similar would be by using pointers. Ex:

 

char *pName = &customer.Name[0];

fgets(pName, 25, f);

 

I would also suggest using constants instead of hard coding all those 25,12,20 numbers around. I did for the sake of simplicity.

Edited by Vortez

Share this post


Link to post
Share on other sites
Adam_42    3629

If you don't want strcpy everywhere, just write a function for that.

void FillCustomer(char *pName, char *pCell, char *pCity)
{
strncpy(customer.Name, pName, 25);
strncpy(customer.City, pName, 12);
strncpy(customer.Cell, pName, 20);
}

 

 

Using strncpy() like that doesn't fix the buffer overflow problem.

 

You need to do something like this or there will be no null terminator when the string is too long:

void FillCustomer(char *pName, char *pCell, char *pCity)
{
  strncpy(customer.Name, pName, 25); customer.Name[25 - 1] = 0;
  strncpy(customer.City, pName, 12); customer.City[12 - 1] = 0;
  strncpy(customer.Cell, pName, 20); customer.Cell[20 - 1] = 0;
}

Share this post


Link to post
Share on other sites
Vortez    2714

Not if you ZeroMemory() the structure beforehand, like it should be done. Or

void FillCustomer(char *pName, char *pCell, char *pCity)
{
  ZeroMemory(&customer, sizeof(customer));
  strncpy(customer.Name, pName, 25); 
  strncpy(customer.City, pName, 12);
  strncpy(customer.Cell, pName, 20);
}
Edited by Vortez

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this