3
#include <string.h>
#include <conio.h>
#include <fstream.h>
#include <string.h>



class mobile
{
int id;
float price;
char *model,*brand;
public:
int getId()
{
    return id;
}
float getPrice(){return price;}
mobile()
{
    brand = new char[5];
    model = new char[5];
    id = 0;
    price = 0.0;
}
void addDetail()
{
    cout<<"\nEnter the mobile ID ";cin>>id;
    cout<<"\nEnter the Price of mobile ";cin>>price;
    cout<<"\nEnter the Brand name of mobile ";cin>>brand;
    cout<<"\nEnter the Model of mobile ";cin>>model;
    ofstream file("database.txt",ios::app);
    char c=' ',n='\n';
    file<<id<<c;
    file<<price<<c;
    file<<brand<<c;
    file<<model<<n;
    file.close();

}

char* getbrand(){return brand;}
char* getModel(){return model;}
~mobile()
{
    delete brand;
    delete model;
}

};

void count()
{
int counter = 0;
char c;
ifstream file("database.txt");
file.seekg(0,ios::beg);
if(!file)cout<<"File not present";
while(file)
{
    file.get(c);
    if(c == '\n')
    {
        counter++;
    }
}
cout<<"The no of entries "<<counter;
file.close();
}

void addMobile()
{
char *model,*brand;

mobile m;
m.addDetail();    
}

void EditMobile()
{
fstream file;
char* brand,*model;
file.open("database.txt",ios::in);
brand = new char;
model = new char;
char c;
int id,pos;
float price;
float f;
if(!file)cout<<"File not present";
else
{


file>>id;cout<<"ID :"<<id<<endl;
file>>price;cout<<"Price :"<<price<<endl;
file>>brand;cout<<"Brand :"<<brand<<endl;
file>>model;cout<<"Model :"<<model<<endl;

}

delete brand;
delete model;
file.close();

}

void admin()
{

char* userpassword;
userpassword = new char;
char* pass;
pass = new char;

cout<<"\n\nEnter the Password";
cin>>userpassword;
fstream fin;
fin.open("password.txt",ios::in | ios::out);
if(!fin)
cout<<"\n\nFile does not exist";
else
{
fin>>pass;
if(strcmp(userpassword,pass) == 0)
{
    char ch;

    count();
    clrscr();
    cout<<"\n\nAcces Granted!!\n\n\tWelcome";
    cout<<"\n\n1.Add a Mobile.";
    cout<<"\n2.Edit a Mobile.";
    cout<<"\n3.Delete a Mobile.";
    cout<<"\n4.View the Database.\n\nEnter Your Choice ";
    ch = getch();
    switch(ch)
    {
    case '1':
        addMobile();
        break;
    case '2':
        EditMobile();
        break;
    case '3':
        //deleteMobile();
        break;

    }
}
else
{
    cout<<"\n\nAcces Denied";
    return;
}
}

fin.close();
delete userpassword;
}
int main()
{
char choice;
clrscr();
cout<<"Welcome to Mobile Store management Program";
cout<<"\n1.Find a Mobile.";
cout<<"\n2.Know Price.";
cout<<"\n3.Know Description.";
cout<<"\n4.Administrator Login.\n\nEnter Your Choice";
choice = getch();
switch(choice)
{
case '1':

    break;
case '4':
    admin();
    break;
}
getch();
return 0;
}

Now in the output I type:

Acces Granted!!

        Welcome

1.Add a Mobile.
2.Edit a Mobile.
3.Delete a Mobile.
4.View the Database.

Enter Your Choice
Enter the mobile ID 1

Enter the Price of mobile 123.34

Enter the Brand name of mobile Nokia

Enter the Model of mobile mynokiamobile

And the output I get in my database.txt file is:

1 123.339996 Nokia mynoki   ile

This space in between are random characters cant be seen here.

Mat
  • 202,337
  • 40
  • 393
  • 406
Pranay Khatri
  • 51
  • 1
  • 1
  • 3

3 Answers3

4

You are exceeding the bounds of the memory allocated for brand and Model.

brand = new char[5];
model = new char[5];

brand and mobile are allocated 5 bytes of memory but your input is longer than that.

The values you enter are:
For brand: "Nokia" which is 6 bytes long( 5 + 1 additional byte is NULL terminator) &
For model: "mynokiamobile" which is 14 bytes long

This results in an Undefined Behavior.
You need to increase these freestore(heap) allocations.

A better C++ approach will be to use std::string instead of character arrays, but I don't know this seems like a homework exercise and maybe you are not allowed to use them, which in my understanding would be pretty lame.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

Those strings are longer than 4 characters (plus the required terminating NULL). And you really can't tell how many letters a user is going to input. Using a std::string instead of char[5] might solve your problem.

When you read the file back in, you'll have to split on spaces. See this question for how to tokenize/split a string in C++.

And see this C++ FAQ question for how to turn strings back into numeric types, once you've split up your input strings.

Community
  • 1
  • 1
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
2

This is C++, why are you using C style strings (brand and model)? brand and model are an array of chars (ie. a C style string):

brand = new char[5];
model = new char[5];

For the mobile brand you're storing "Nokia" + the NUL terminator '\0', which is 6 chars. For model you're entering in "mynokiamobile", which is well over 5 chars. I also don't understand why you'd dynamically allocate the array of fixed size with new either, but that's irrelevant.

Bottom line, use std::string and make your code more C++-like than C.

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
  • well thats ok.. but i guess this `brand = new char;` `model = new char;` allocates dynamically as many characters as inputed.. – Pranay Khatri Oct 29 '11 at 09:00
  • @PranayKhatri it won't do that at all. It'll allocate memory for a **single** `char`. The `std::string` container will look after how much memory is required to hold your string/characters. – AusCBloke Oct 29 '11 at 09:02
  • it doesnt allocate single char entity in my compiler... i have tried it would allocate that much bytes that you enter – Pranay Khatri Oct 29 '11 at 09:06
  • @PranayKhatri `new char` allocates memory for a single `char` on the heap, `new char[X]` allocates memory for `X` `char`s. I don't think you have a magic compiler that knows how much input the user's going to type in (which is why you use `std::string` in C++). – AusCBloke Oct 29 '11 at 09:09