By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,852 Members | 2,219 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,852 IT Pros & Developers. It's quick & easy.

Saving to file

P: 17
This is my code for a database, whenever i save the database to the file 'database.txt' and display the results i get this;

name - (correct, is what i put in)
pin - 3435973836
slew rate - -9.25596e+061

these values are the same for every entry i add, i cant seem fo figure out why.

Plus, the text file i save to is supposed to have the format of

length

Name
Pin
Slew

Name
Pin Slew

However, the text file looks nothing like it, any ideas as to why it isnt in this format??

code;
Expand|Select|Wrap|Line Numbers
  1. #include <stdafx.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string.h>
  5. using namespace std;
  6.  
  7. struct OpAmps {
  8.   char Name[20];  // the name of the op-amp (e.g. "741")
  9.   unsigned int PinCount;  // the number of pins in the package
  10.   double SlewRate;  // the slew rate in volts per microsecond
  11. };
  12.  
  13. #define DATABASE_MAX 10
  14.  
  15. #define DATABASE_FILENAME "database.txt"
  16.  
  17. // function prototypes
  18.  
  19. void Enter(OpAmps&, unsigned long&);
  20. void Save(const OpAmps*, const unsigned long&);
  21. void Load(OpAmps*, unsigned long&);
  22. void Sort(OpAmps*, unsigned long&);
  23. void Display(OpAmps*, const unsigned long&);
  24.  
  25. int SortByName(const void*, const void*);
  26. int SortBySlewRate(const void*, const void*);
  27.  
  28. int main()
  29. {
  30.   OpAmps OpAmp[DATABASE_MAX];   // the database
  31.   unsigned long database_length = 0;  // the number of elements in the database
  32.   char UserInput;
  33.  
  34.   // loop until the user wishes to exit
  35.   while (1) {
  36.  
  37.     // show the menu of options
  38.     cout << endl;
  39.     cout << "Op-amp database menu" << endl;
  40.     cout << "--------------------" << endl;
  41.     cout << "1. Enter a new op-amp into the database" << endl;
  42.     cout << "2. Save the database to disk" << endl;
  43.     cout << "3. Load the database from disk" << endl;
  44.     cout << "4. Sort the database" << endl;
  45.     cout << "5. Display the database" << endl;
  46.     cout << "6. Exit from the program" << endl << endl;
  47.  
  48.     // get the user's choice
  49.     cout << "Enter your option: ";
  50.     cin >> UserInput;
  51.     cout << endl;
  52.  
  53.     // act on the user's input
  54.     switch(UserInput) {
  55.       case '1':
  56.         Enter(OpAmp[database_length], database_length);
  57.         break;
  58.  
  59.       case '2':
  60.         Save(OpAmp, database_length);
  61.         break;
  62.  
  63.       case '3':
  64.         Load(OpAmp, database_length);
  65.         break;
  66.  
  67.       case '4':
  68.         Sort(OpAmp, database_length);
  69.         break;
  70.  
  71.       case '5':
  72.         Display(OpAmp, database_length);
  73.         break;
  74.  
  75.       case '6':
  76.         return 0;
  77.  
  78.       default:
  79.         cout << "Invalid entry" << endl << endl;
  80.         break;
  81.     }
  82.   }
  83. }
  84.  
  85.  
  86. void Enter(OpAmps& OpAmp, unsigned long& length)
  87. // if the database is full, inform the user
  88. {
  89.     char line[20];
  90.     unsigned int Pin;
  91.     double Slew;
  92.     bool cont=false;
  93.  
  94.     if (length == 10)
  95.     {
  96.         cerr << "The database is full" << endl;
  97.     }
  98.  
  99. // if the database is not full, get the data from the user and alter the database length
  100.  
  101.     else
  102.         while (cont==false)
  103.         {
  104.             cout << "Enter Operational Amplifier name: ";
  105.             cin.ignore();
  106.             cin.getline(line, sizeof(line), '\n');
  107.             strcpy_s(OpAmp.Name, line);
  108.             cont=true;
  109.         }
  110.  
  111.  
  112.     cont = false;
  113.     while (cont==false)
  114.     {
  115.         cout << endl << "Enter number of pins: ";
  116.         cin.ignore();
  117.         cin.getline(line, sizeof(line));
  118.         scanf_s(line,"%u",&Pin), '\n';
  119.         OpAmp.PinCount=Pin; 
  120.         cont=true;
  121.     }
  122.  
  123.     cont = false;
  124.     while (cont==false)
  125.     {
  126.         cout << endl << "Enter slew rate: ";
  127.         cin.ignore();
  128.         cin.getline(line, sizeof(line), '\n');
  129.         scanf_s(line,"%f",&Slew);
  130.         OpAmp.SlewRate=Slew; 
  131.         cont=true;
  132.     }
  133.     length++;
  134.  
  135.     cout << endl << "Operator Amplifier in memory, to save select option 2 from main menu" << endl;
  136. }
  137.  
  138. void Save(const OpAmps* OpAmp, const unsigned long& length)
  139. {  
  140.   fstream output_file;  // file stream for output
  141.  
  142.   // open the file
  143.   //<enter code here>
  144.   output_file.open(DATABASE_FILENAME, ios::out);
  145.   if (!output_file.good())
  146.   {
  147.       cout << "Could not create file";
  148.       exit (1);
  149.   }
  150.  
  151.   cout << "Opened file to save data to" << endl;
  152.  
  153.   // write length information to file
  154.   output_file << length << endl << endl;
  155.  
  156.   // write data to file
  157.   unsigned int i;
  158.   for (i=0;i<length;i++);
  159.   {
  160.       output_file.write((char *)(&OpAmp[i]), sizeof(OpAmp));
  161.   }
  162.   cout << length << " entry(s) added to database" << endl;
  163.   // close the file
  164.   output_file.close();
  165. }
  166.  
  167. void Load(OpAmps* OpAmp, unsigned long& length)
  168. {  
  169.   fstream input_file;  // file stream for input
  170.  
  171.    //open the file
  172.   input_file.open(DATABASE_FILENAME, ios::in);
  173.   if (!input_file.good())
  174.   {
  175.       cout << "Could not open file";
  176.       exit (1);
  177.   }
  178.  
  179.   // load database length information from file
  180.   else
  181.   {
  182.       cout << "File opened" << endl;
  183.  
  184.       char templine[20];
  185.       char emptyline[20];
  186.  
  187.       OpAmps* pOpAmps = &OpAmp[0];
  188.  
  189.       input_file >> emptyline;
  190.       unsigned long tempLn=0;
  191.       scanf_s(emptyline, "%lu", &tempLn);
  192.       cout << tempLn << endl;
  193.       length = tempLn;
  194.  
  195.       if (length==0)
  196.       {
  197.         cout << "Database empty" << endl;
  198.       }
  199.       else 
  200.       {
  201.               unsigned int Pin;
  202.               float Slew;
  203.  
  204.               for (unsigned int i=0;i<length;i++)
  205.               {
  206.                  input_file>>templine;
  207.                  cout<<templine<<endl;
  208.                  strcpy_s((*pOpAmps).Name,templine);
  209.  
  210.                  input_file>>templine;
  211.  
  212.                  if (scanf_s(templine,"%u",&Pin))
  213.                  {
  214.                      (*pOpAmps).PinCount=Pin;
  215.                      cout<<Pin<<endl;
  216.                  }
  217.                  else
  218.                  {
  219.                      cout<<"Error reading "<< ((*pOpAmps).Name) <<endl;
  220.                  }
  221.  
  222.                  input_file>>templine;
  223.  
  224.                  if (scanf_s(templine,"%f",&Slew))
  225.                  {
  226.                      (*pOpAmps).SlewRate=Slew;
  227.                      cout<<Slew<<endl;
  228.                  }
  229.                  else
  230.                  {
  231.                      cout<<"Error reading" << ((*pOpAmps).Name) << endl;
  232.                  }
  233.                  pOpAmps++;
  234.               }
  235.               cout<<"Total "<<length<< "entry(s) read"<<endl;
  236.       }
  237.   }
  238.  
  239.  
  240.  
  241.  
  242.  
  243.   // close the file
  244.   input_file.close();
  245. }
  246.  
  247.  
  248.   void Sort(OpAmps* OpAmp, unsigned long& length)
  249. {  
  250.   char UserInput;
  251.  
  252.   // show the menu of options
  253.   cout << endl;
  254.   cout << "Sorting options" << endl;
  255.   cout << "---------------" << endl;
  256.   cout << "1. To sort by name" << endl;
  257.   cout << "2. To sort by slew rate" << endl;
  258.   cout << "3. No sorting" << endl << endl;
  259.  
  260.   // get the user's choice of sorting operation required
  261.   cout << "Enter your option: ";
  262.   cin >> UserInput;
  263.   cout << endl;
  264.  
  265.   // act on the user's input
  266.   //<enter code here>
  267.   switch(UserInput)
  268.   {
  269.  
  270.     case '1':
  271.         qsort((void*)&OpAmp[0], length, sizeof(OpAmp[0]), SortByName);
  272.         break;
  273.  
  274.     case '2':
  275.         qsort((void*)&OpAmp[0], length, sizeof(OpAmp[0]), SortBySlewRate);
  276.         break;
  277.  
  278.     case '3':
  279.  
  280.         break;
  281.  
  282.     default:
  283.         cout << "Invalid entry" << endl << endl;
  284.         break;
  285.   }
  286.  
  287. }
  288.  
  289.  
  290.   int SortByName(const void* Value1, const void* Value2)
  291. {  
  292.   //<enter code here>
  293.     return strcmp((*(OpAmps*)Value1).Name, (*(OpAmps*)Value2).Name);
  294. }
  295.  
  296.  
  297.   int SortBySlewRate(const void* Value1, const void* Value2)
  298. {  
  299.   //<enter code here>
  300.     if ((*(OpAmps*)Value1).SlewRate<(*(OpAmps*)Value2).SlewRate)
  301.     {
  302.       return -1;
  303.     }    
  304.     else if ((*(OpAmps*)Value1).SlewRate>(*(OpAmps*)Value2).SlewRate) 
  305.     {
  306.      return 1;
  307.     }
  308.     else
  309.     {
  310.      return 0;
  311.     }
  312. }
  313.  
  314. void Display(OpAmps* OpAmp, const unsigned long& length)
  315. {
  316.     OpAmps* pOpAmps;
  317.     pOpAmps=&OpAmp[0];
  318.  
  319.   // if the database is empty, inform the user
  320.   if (length==0)
  321.   {
  322.       cout << "The database is empty";
  323.   }
  324.   // if the database is not empty, display all the elements in the database
  325.   //<enter code here>
  326.   else
  327.   {
  328.       for (unsigned int i=0;i<length;i++)
  329.       {
  330.           cout << "Operational Amplifier name : " << (*pOpAmps).Name << endl;
  331.           cout << "Number of pins : " << (*pOpAmps).PinCount << endl;
  332.           cout << "Slew Rate : " << (*pOpAmps).SlewRate << " Volts/microsecond" << endl << endl;
  333.           pOpAmps++;
  334.   }
  335.   }
  336. }
Mar 15 '07 #1
Share this Question
Share on Google+
7 Replies


Ganon11
Expert 2.5K+
P: 3,652
The problem is likely with the line

Expand|Select|Wrap|Line Numbers
  1. output_file.write((char *)(&OpAmp[i]), sizeof(OpAmp));
inside the for...loop of the Save function. You are casting the first portion to a char*, but the thing you are casting is the address of an OpAmps object. This is probably a bad cast, which is giving you the strange results.

Also, the second argument is using sizeof(OpAmp), which is the size of the array you are using - should it be sizeof(OpAmps), the struct?
Mar 15 '07 #2

Expert 100+
P: 1,510
you are not reading the pin and slew rate values correctly in function Enter(), try
Expand|Select|Wrap|Line Numbers
  1. void Enter(OpAmps& OpAmp, unsigned long& length)
  2. // if the database is full, inform the user
  3. {
  4.     char line[20];
  5.     unsigned int Pin;
  6.     double Slew;
  7.     bool cont=false;
  8.  
  9.     if (length == 10)
  10.     {
  11.         cerr << "The database is full" << endl;
  12.     }
  13.  
  14. // if the database is not full, get the data from the user and alter the database length
  15.  
  16.     else
  17.         while (cont==false)
  18.         {
  19.             cout << "Enter Operational Amplifier name: ";
  20.             cin.ignore();
  21.             cin.getline(line, sizeof(line), '\n');
  22.             strcpy(OpAmp.Name, line);
  23.             cont=true;
  24.         }
  25.  
  26.  
  27.     cont = false;
  28.     while (cont==false)
  29.     {
  30.         cout << endl << "Enter number of pins: ";
  31.         //cin.ignore();
  32.         //cin.getline(line, sizeof(line));
  33.         scanf("%u",&Pin), '\n';
  34.         OpAmp.PinCount=Pin; 
  35.         cont=true;
  36.     }
  37.  
  38.     cont = false;
  39.     while (cont==false)
  40.     {
  41.         cout << endl << "Enter slew rate: ";
  42.         //cin.ignore();
  43.         //cin.getline(line, sizeof(line), '\n');
  44.         scanf("%lf",&Slew);
  45.         OpAmp.SlewRate=Slew; 
  46.         cont=true;
  47.     }
  48.     length++;
  49. cout << OpAmp.Name << " " <<  OpAmp.PinCount << " " <<  OpAmp.SlewRate << " " << endl;
  50.     cout << endl << "Operator Amplifier in memory, to save select option 2 from main menu" << endl;
  51. }
  52.  
  53.  
it is a good idea in a function such as enter where you read in data to print it out to screen so you can check the read worked
Mar 15 '07 #3

P: 17
So in the console that works fine, but in the database.txt file the program creates the information is not stored conrrectly. The file only contains the length and then alot of garbage, cant seem to pinpoint where the code is wrong
ideas??
Mar 15 '07 #4

P: 17
I have changed a part of the save function to this:

unsigned int i;
for (i=0;i<length;i++);
{
//output_file.write((const char*)&OpAmp[i], sizeof(OpAmps));
output_file << endl;
output_file << OpAmp[i].Name << endl;
output_file << OpAmp[i].PinCount << endl;
output_file << OpAmp[i].SlewRate << endl;

but it is still not saving the correct text to file, all just garbage still. All the online help i have looked at doesnt help me solve the problem...
Mar 15 '07 #5

Expert 100+
P: 1,510
I have changed a part of the save function to this:

unsigned int i;
for (i=0;i<length;i++);
{
//output_file.write((const char*)&OpAmp[i], sizeof(OpAmps));
output_file << endl;
output_file << OpAmp[i].Name << endl;
output_file << OpAmp[i].PinCount << endl;
output_file << OpAmp[i].SlewRate << endl;

but it is still not saving the correct text to file, all just garbage still. All the online help i have looked at doesnt help me solve the problem...
you have a ; on the end of your for() statement - this will terminate the for and on exit i will = length so garbage is written to the file
Mar 15 '07 #6

P: 17
thanks, so last thing, in the Load function, i always get a length of zero, it is supposed to read the first line of the text file and then read the corresponding entries, the first line in the file is the number 3, so it should read three, but doesnt, ideas??

Expand|Select|Wrap|Line Numbers
  1. void Load(OpAmps* OpAmp, unsigned long& length)
  2. {  
  3.   fstream input_file;  // file stream for input
  4.  
  5.    //open the file
  6.  
  7.   input_file.open(DATABASE_FILENAME, ios::in);
  8.   if (!input_file.good())
  9.   {
  10.       cout << "Could not open file";
  11.       exit (1);
  12.   }
  13.  
  14.   // load database length information from file
  15.  
  16.   else
  17.   {
  18.       cout << "File opened" << endl;
  19.  
  20.   // load data from file
  21.  
  22.       char templine[20];
  23.       char emptyline[20];
  24.  
  25.       OpAmps* pOpAmps = &OpAmp[0];
  26.  
  27.       input_file >> emptyline;
  28.       unsigned long tempLn=0;
  29.       if (scanf_s(emptyline, "%lu", &tempLn))
  30.       {
  31.           cout << tempLn << endl;
  32.           length = tempLn;
  33.       }
  34.       else
  35.       {
  36.           cout << "Error" << endl;
  37.       }
  38.  
  39.       if (length==0)
  40.       {
  41.         cout << "Database empty" << endl;
  42.       }
  43.       else 
  44.       {
  45.               unsigned int Pin;
  46.               float Slew;
  47.  
  48.               for (unsigned int i=0;i<length;i++)
  49.               {
  50.                  input_file>>templine;
  51.                  cout<<templine<<endl;
  52.                  strcpy_s((*pOpAmps).Name,templine);
  53.  
  54.                  input_file>>templine;
  55.  
  56.                  if (scanf_s(templine,"%u",&Pin))
  57.                  {
  58.                      (*pOpAmps).PinCount=Pin;
  59.                      cout<<Pin<<endl;
  60.                  }
  61.                  else
  62.                  {
  63.                      cout<<"Error reading "<< ((*pOpAmps).Name) <<endl;
  64.                  }
  65.  
  66.                  input_file>>templine;
  67.  
  68.                  if (scanf_s(templine,"%lf",&Slew))
  69.                  {
  70.                      (*pOpAmps).SlewRate=Slew;
  71.                      cout<<Slew<<endl;
  72.                  }
  73.                  else
  74.                  {
  75.                      cout<<"Error reading" << ((*pOpAmps).Name) << endl;
  76.                  }
  77.                  pOpAmps++;
  78.               }
  79.               cout<<"Total "<<length<< "entry(s) read"<<endl;
  80.       }
  81.   }
Mar 15 '07 #7

Ganon11
Expert 2.5K+
P: 3,652
Instead of reading the first line into a character array, since you know it will be an int value, why not try reading the value directly into length? Something like:

Expand|Select|Wrap|Line Numbers
  1. input_file >> length;
I only say this because I've never used scanf_s and am not sure if this line is producing errors.
Mar 16 '07 #8

Post your reply

Sign in to post your reply or Sign up for a free account.