printing text file string contents (array) - padded characters

Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: May 2008
Posts: 96
Reputation: QuantNeeds is an unknown quantity at this point 
Solved Threads: 0
QuantNeeds QuantNeeds is offline Offline
Junior Poster in Training

printing text file string contents (array) - padded characters

 
0
  #1
Jul 28th, 2008
I am not sure how to prevent the padded characters within a string array from printing. The user inputs the information in function enterRecords() and then prints in outputLine(ostream &output, const Tools &record ) function.

I am having issues with outputline when I try to print to screen and then use it to print to the text file.


My code is the following:

  1. // default Tools constructor
  2. Tools::Tools( int partNumberValue,string toolNameValue, int inStockValue, double unitPriceValue)
  3. {
  4. setPartNumber( partNumberValue);
  5. setToolName( toolNameValue );
  6. setInStock( inStockValue);
  7. setUnitPrice( unitPriceValue );
  8. } // end Tools constructor
  9.  
  10.  
  11. // get tool identification number
  12. int Tools::getPartNumber() const
  13. {
  14. return partNumber;
  15. }
  16. // set tool identification numbers
  17. void Tools::setPartNumber( int partNumberValue)
  18. {
  19. partNumber = partNumberValue;
  20. }
  21. void Tools::validatePartNumber(int checkPart)
  22. {
  23. if(checkPart > 0 && checkPart <= 100)
  24. partNumber = checkPart;
  25. else
  26. {
  27. bool flag = false;
  28. while(flag == false)
  29. {
  30. cout << "Part number is a record, an integer within range 1 to 100.";
  31. cout << "\nRe-enter tool identification number (1 to 100, 0 to end input)\n? ";
  32. cin >> checkPart;
  33.  
  34. if(checkPart > 0 && checkPart <= 100)
  35. {
  36. partNumber = checkPart;
  37. flag = true;
  38. }
  39. } // end while loop
  40. } // end if
  41. } // end function
  42.  
  43. // get tool name
  44. string Tools::getToolName() const
  45. {
  46. return toolName;
  47. }
  48. // set the tool name
  49. void Tools::setToolName(string toolNameString)
  50. {
  51. // copy at most 20 characters for the tool name
  52. const char *toolNameValue = toolNameString.data();
  53. int length = int(toolNameString.size());
  54. length = (length < 20 ? length : 19);
  55. strncpy(toolName, toolNameValue, length);
  56. //toolName[ length ] = '\0'; // append null character to lastName
  57. }
  58.  
  59. // get in-stock quantity for the tool
  60. int Tools::getInStock() const
  61. {
  62. return inStock;
  63. }
  64. // set in-stock quantity for the tool
  65. void Tools::setInStock( int inStockValue)
  66. {
  67. inStock= inStockValue;
  68. }
  69.  
  70. // get unit price for each tool
  71. double Tools::getUnitPrice() const
  72. {
  73. return unitPrice;
  74. }
  75. // set unit price for each tool
  76. void Tools::setUnitPrice( double unitPriceValue )
  77. {
  78. unitPrice = unitPriceValue;
  79. }
  80. void Tools::createAndInitializeTextFile()
  81. {
  82. ofstream outTools( "hardware.dat", ios::out | ios::binary );
  83.  
  84. // exit program if ofstream could not open file
  85. if ( !outTools )
  86. {
  87. cerr << "File could not be opened." << endl;
  88. exit( 1 );
  89. }
  90.  
  91. Tools blankTool; // constructor zeros out each data member
  92.  
  93. // output 100 blank records to file
  94. for ( int i = 0; i < 100; i++ )
  95. outTools.write( reinterpret_cast < const char * >( &blankTool ), sizeof ( Tools ) );
  96. }
  97.  
  98. void Tools::enterRecords()
  99. {
  100. fstream outTools( "hardware.dat", ios::in | ios::out | ios::binary );
  101.  
  102. // exit program if fstream cannot open file
  103. if ( !outTools )
  104. {
  105. cerr << "File could not be opened." << endl;
  106. exit( 1 );
  107. } // end if
  108.  
  109. // require user to specify a tool identification number
  110. cout << "Enter tool identification number (1 to 100, 0 to end input): ";
  111. cin >> partNumber;
  112.  
  113. Tools tool; // create the object
  114.  
  115. // user enters information, which is copied into file
  116. while (partNumber != 0)
  117. {
  118. validatePartNumber(partNumber);
  119.  
  120. // user enters tool name, quantity and unit price
  121. cout << "Enter the tool name: ";
  122. fflush(stdin);
  123. cin.getline( toolName, 20, '\n' );
  124.  
  125. cout << "Enter the quantity in stock: ";
  126. cin >> inStock;
  127. cout << "Enter the unit price: ";
  128. cin >> unitPrice;
  129.  
  130. // set the record for the part number, tool name, quantity in stock, and unit price
  131. tool.setPartNumber( partNumber );
  132. tool.setToolName( toolName );
  133. tool.setInStock( inStock );
  134. tool.setUnitPrice( unitPrice );
  135.  
  136. // seek position in file of user-specified record
  137. outTools.seekp( ( tool.getPartNumber() - 1 ) * sizeof ( Tools ) );
  138.  
  139. // write user-specified information in file
  140. outTools.write( reinterpret_cast < const char * >( &tool ),sizeof ( Tools) );
  141.  
  142. //enable user to enter another account
  143. cout << "\nEnter tool identification number (1 to 100, 0 to end input): ";
  144. cin >> partNumber;
  145.  
  146. } // end while loop
  147.  
  148. } // end enterRecords function
  149.  
  150. bool Tools::test()
  151. {
  152. ifstream inTools( "hardware.dat", ios::in | ios::binary );
  153.  
  154. // exit program if ifstream cannot open file
  155. if ( !inTools )
  156. {
  157. cerr << "File could not be opened." << endl;
  158. exit( 1 );
  159. } // end if
  160.  
  161. Tools tool;
  162.  
  163. bool answer = false;
  164.  
  165. if ( tool.getPartNumber() != 0 )
  166. answer = true;
  167. else
  168. answer = false;
  169.  
  170. return answer;
  171. }
  172. void Tools::processChoice()
  173. {
  174. // open file for reading and writing
  175. fstream inOutTools( "hardware.dat", ios::in | ios::out | ios::binary );
  176.  
  177. // exit program if fstream cannot open file
  178. if ( !inOutTools )
  179. {
  180. cerr << "File could not be opened." << endl;
  181. exit ( 1 );
  182. } // end if
  183.  
  184. int choice; // store user choice
  185.  
  186. // enable user to specify action
  187. while ( ( choice = enterChoice() ) != END )
  188. {
  189. switch ( choice )
  190. {
  191. case PRINT: // create text file from record file
  192. printTextFile( inOutTools );
  193. break;
  194. case UPDATE: // update record
  195. updateRecord( inOutTools );
  196. break;
  197. case NEW: // create record
  198. newRecord( inOutTools );
  199. break;
  200. case DELETE: // delete existing record
  201. deleteRecord( inOutTools );
  202. break;
  203. default: // display error if user does not select valid choice
  204. cerr << "Incorrect choice" << endl;
  205. break;
  206. } // end switch
  207.  
  208. inOutTools.clear(); // reset end-of-file indicator
  209. } // end while
  210. }
  211.  
  212. // enable user to input menu choice
  213. int Tools::enterChoice()
  214. {
  215. // display available options
  216. cout << "\nEnter your choice:" << endl
  217. << "1 - store a formatted text file of accounts - called \"print.txt\" for printing." << endl
  218. << "2 - update an account" << endl
  219. << "3 - add a new account" << endl
  220. << "4 - delete an account" << endl
  221. << "5 - end program\n? ";
  222.  
  223. int menuChoice;
  224. cin >> menuChoice; // input menu selection from user
  225. //menuChoice = 1;
  226. return menuChoice;
  227. }
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248. // create formatted text file for printing
  249. void Tools::printTextFile(fstream &readFromFile )
  250. {
  251. // create text file
  252. ofstream outPrintFile( "print.txt", ios::out );
  253.  
  254. // exit program if ofstream cannot create file
  255. if ( !outPrintFile )
  256. {
  257. cerr << "File could not be created." << endl;
  258. exit( 1 );
  259. } // end if
  260.  
  261. outPrintFile << left << setw( 10 ) << "Tool Identification" << right << setw( 20 )<< "Tool Name" << setw( 11 )
  262. << "Quantity" << right << setw( 10 ) << "Unit Price" << endl;
  263.  
  264. // set file-position pointer to beginning of readFromFile
  265. readFromFile.seekg( 0 );
  266.  
  267. // read first record from record file
  268. Tools tool;
  269. readFromFile.read( reinterpret_cast < char * >( &tool ),
  270. sizeof ( Tools ) );
  271.  
  272. // copy all records from record file into text file
  273. while ( !readFromFile.eof() )
  274. {
  275. // write single record to text file
  276. if ( tool.getPartNumber() != 0 ) // skip empty records
  277. outputLine( outPrintFile, tool );
  278.  
  279. // read next record from record file
  280. readFromFile.read( reinterpret_cast < char * >( &tool),
  281. sizeof ( Tools ) );
  282. } // end while
  283. }
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290. // update the new quantity and unit price in the record
  291. void Tools::updateRecord( fstream &updateFile )
  292. {
  293. // obtain number of account to update
  294. int partNumber = getPart( "\nEnter tool part identification number to update: " );
  295.  
  296. // move file-position pointer to correct record in file
  297. updateFile.seekg( ( partNumber - 1 ) * sizeof ( Tools ) );
  298.  
  299. // read first record from file
  300. Tools tool;
  301. updateFile.read( reinterpret_cast < char * >( &tool ),
  302. sizeof( Tools ) );
  303.  
  304. // update record
  305. if ( tool.getPartNumber() != 0 )
  306. {
  307. outputLine( cout, tool ); // display the record
  308.  
  309. // request user to specify new quantity
  310. cout << "\nEnter new current quantity: ";
  311. int currentQuantity; // change the quantity
  312. cin >> currentQuantity;
  313. tool.setInStock( currentQuantity ); // update record
  314.  
  315. // request user enter a new unit price
  316. cout << "\nEnter new unit price for the tool: ";
  317. double currentPrice; // change the unit price
  318. cin >> currentPrice;
  319. tool.setUnitPrice( currentPrice ); // update record
  320.  
  321. outputLine( cout, tool ); // display the record
  322.  
  323.  
  324. // move file-position pointer to correct record in file
  325. updateFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) );
  326.  
  327. // write updated record over old record in file
  328. updateFile.write( reinterpret_cast< const char * >( &tool ),
  329. sizeof( Tools ) );
  330. } // end if
  331. else // display error if account does not exist
  332. cerr << "\nPart identification # " << partNumber << " has no information." << endl;
  333. } // end function updateRecord
  334.  
  335.  
  336.  
  337.  
  338.  
  339. // create and insert record
  340. void Tools::newRecord( fstream &insertInFile )
  341. {
  342. // obtain number of account to create
  343. int partNumber = getPart( "Enter new part number: " );
  344. validatePartNumber(partNumber);
  345.  
  346. // move file-position pointer to correct record in file
  347. insertInFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) );
  348.  
  349. // read record from file
  350. Tools tool;
  351. insertInFile.read( reinterpret_cast < char * >( &tool ),
  352. sizeof( Tools ) );
  353.  
  354. // create record, if record does not previously exist
  355. if ( tool.getPartNumber() == 0 )
  356. {
  357. // user enters tool name, quantity and unit price
  358. cout << "\nEnter the tool name: ";
  359. fflush(stdin);
  360. cin.getline( toolName, 20, '\n' );
  361.  
  362. cout << "\nEnter the quantity in stock: ";
  363. cin >> inStock;
  364. cout << "Enter the unit price: ";
  365. cin >> unitPrice;
  366.  
  367. // set the record for the part number, tool name, quantity in stock, and unit price
  368. tool.setPartNumber( partNumber );
  369. tool.setToolName( toolName );
  370. tool.setInStock( inStock );
  371. tool.setUnitPrice( unitPrice );
  372.  
  373.  
  374. // move file-position pointer to correct record in file
  375. insertInFile.seekp( ( partNumber - 1 ) * sizeof( Tools ) );
  376.  
  377. // insert record in file
  378. insertInFile.write( reinterpret_cast < const char * >( &tool ),
  379. sizeof( Tools ) );
  380. } // end if
  381. else // display error if account already exists
  382. cerr << "\n\nPart # " << partNumber << " already contains information." << endl;
  383. } // end function newRecord
  384.  
  385.  
  386.  
  387.  
  388. // delete an existing record
  389. void Tools::deleteRecord( fstream &deleteFromFile )
  390. {
  391. // obtain number of account to delete
  392. int partNumber = getPart( "Enter the tool to delete" );
  393.  
  394. // move file-position pointer to correct record in file
  395. deleteFromFile.seekg( ( partNumber - 1 ) * sizeof( Tools ) );
  396.  
  397. // read record from file
  398. Tools tool;
  399. deleteFromFile.read( reinterpret_cast < char * >( &tool ),
  400. sizeof( Tools ) );
  401.  
  402. // delete record, if record exists in file
  403. if ( tool.getPartNumber() != 0 )
  404. {
  405. Tools blankTool; // create blank record
  406.  
  407. // move file-position pointer to correct record in file
  408. deleteFromFile.seekp( ( partNumber - 1 ) *
  409. sizeof( Tools ) );
  410.  
  411. // replace existing record with blank record
  412. deleteFromFile.write(
  413. reinterpret_cast < const char * >( &blankTool ),
  414. sizeof( Tools ) );
  415.  
  416. cout << "\nPart # " << partNumber << " deleted.\n";
  417. } // end if
  418. else // display error if record does not exist
  419. cerr << "\nPart # " << partNumber << " is empty.\n";
  420. } // end deleteRecord
  421.  
  422.  
  423.  
  424.  
  425.  
  426. // display single record
  427. void Tools::outputLine(ostream &output, const Tools &record )
  428. {
  429. cout << left << setw( 10 ) << record.getPartNumber() << setw( 16 ) << record.getToolName() << right << setw(9) << record.getInStock()
  430. << setw( 10 ) << setprecision(2) << right << fixed << showpoint << record.getUnitPrice() << endl;
  431. }
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,662
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1501
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: printing text file string contents (array) - padded characters

 
0
  #2
Jul 28th, 2008
>>I am not sure how to prevent the padded characters within a string array from printing.

Post an example of such a string -- something like this perhaps:
  1. " Hello World "
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 96
Reputation: QuantNeeds is an unknown quantity at this point 
Solved Threads: 0
QuantNeeds QuantNeeds is offline Offline
Junior Poster in Training

Re: printing text file string contents (array) - padded characters

 
0
  #3
Jul 28th, 2008
Originally Posted by Ancient Dragon View Post
>>I am not sure how to prevent the padded characters within a string array from printing.

Post an example of such a string -- something like this perhaps:
  1. " Hello World "

Not sure what you mean by this but below are the 2 functions and the screen print out for an example on how it is printing my array with the tool names.

Basically the characters ( ? padded characters) are coming out when the record prints.
Also for my first line / record, it is not aligning it like the rest of the records.

  1. void Tools::printTextFile(fstream &readFromFile )
  2. {
  3. // create text file
  4. ofstream outPrintFile( "print.txt", ios::out );
  5.  
  6. // exit program if ofstream cannot create file
  7. if ( !outPrintFile )
  8. {
  9. cerr << "File could not be created." << endl;
  10. exit( 1 );
  11. } // end if
  12.  
  13. // print header in the test file (formatted this way to easily view)
  14. outPrintFile << left << setw(10) << "Tool Id"
  15. << right << setw(10)<< " Tool Name"
  16. << right << setw(20) << "Quantity"
  17. << right << setw(20) << " Unit Price" << endl;
  18.  
  19. // print header in the output prompt screen
  20. cout << left << setw(10) << "\nTool Id"
  21. << left << setw(15)<< " Tool Name"
  22. << right << setw(20) << "Quantity"
  23. << right << setw(16) << "Unit Price" << endl;
  24.  
  25. // set file-position pointer to beginning of readFromFile
  26. readFromFile.seekg( 0 );
  27.  
  28. // read first record from record file
  29. Tools tool;
  30. readFromFile.read( reinterpret_cast < char * >( &tool ),
  31. sizeof ( Tools ) );
  32.  
  33. // copy all records from record file into text file
  34. while ( !readFromFile.eof() )
  35. {
  36. // write single record to text file
  37. if ( tool.getPartNumber() != 0 ) // skip empty records
  38. outputLine( outPrintFile, tool );
  39.  
  40. // read next record from record file
  41. readFromFile.read( reinterpret_cast < char * >( &tool),
  42. sizeof ( Tools ) );
  43. } // end while
  44. }

  1. // display single record
  2. void Tools::outputLine(ostream &output, const Tools &record )
  3. {
  4. output << left << setw(10 ) << record.getPartNumber()
  5. << setw( 16 ) << record.getToolName()
  6. << right << setw(9) << record.getInStock()
  7. << right << setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;
  8.  
  9. cout << left << setw(10) << record.getPartNumber()
  10. << setw( 16 ) << record.getToolName()
  11. << right << setw(12) << record.getInStock()
  12. << right<< setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;
  13. }

And this is what happens:
http://i24.photobucket.com/albums/c2...176/screen.jpg
Last edited by QuantNeeds; Jul 28th, 2008 at 9:52 pm.
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,662
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1501
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: printing text file string contents (array) - padded characters

 
0
  #4
Jul 28th, 2008
IMG tags don't work here. Hit the Advanced button, scroll down, then select the Manage Attachments. That will let you load an image file to your post.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 96
Reputation: QuantNeeds is an unknown quantity at this point 
Solved Threads: 0
QuantNeeds QuantNeeds is offline Offline
Junior Poster in Training

Re: printing text file string contents (array) - padded characters

 
0
  #5
Jul 28th, 2008
Ok - yep I have been working on it and I still have the same problems:

1) the way its reading in the strings and not clearing the past entries for the new inputs (just tags remaining at the end

2) prints the padded characters

3) for some reason my first record is not aligned

Attached is the screen shot and below is the code

  1.  
  2. void Tools::enterRecords()
  3. {
  4. fstream outTools( "hardware.dat", ios::in | ios::out | ios::binary );
  5.  
  6. // exit program if fstream cannot open file
  7. if ( !outTools )
  8. {
  9. cerr << "File could not be opened." << endl;
  10. exit( 1 );
  11. } // end if
  12.  
  13. // require user to specify a tool identification number
  14. cout << "Enter tool identification number (1 to 100, 0 to end input): ";
  15. cin >> partNumber;
  16.  
  17. Tools tool; // create the object
  18.  
  19. // user enters information, which is copied into file
  20. while (partNumber != 0)
  21. {
  22. validatePartNumber(partNumber);
  23.  
  24. // user enters tool name, quantity and unit price
  25. cout << "Enter the tool name: ";
  26. fflush(stdin);
  27. cin.getline( toolName, 20, '\n' );
  28.  
  29. cout << "Enter the quantity in stock: ";
  30. cin >> inStock;
  31. cout << "Enter the unit price: ";
  32. cin >> unitPrice;
  33.  
  34. // set the record for the part number, tool name, quantity in stock, and unit price
  35. tool.setPartNumber( partNumber );
  36. tool.setToolName( toolName );
  37. tool.setInStock( inStock );
  38. tool.setUnitPrice( unitPrice );
  39.  
  40. // seek position in file of user-specified record
  41. outTools.seekp( ( tool.getPartNumber() - 1 ) * sizeof ( Tools ) );
  42.  
  43. // write user-specified information in file
  44. outTools.write( reinterpret_cast < const char * >( &tool ),sizeof ( Tools) );
  45.  
  46. //enable user to enter another account
  47. cout << "\nEnter tool identification number (1 to 100, 0 to end input): ";
  48. cin >> partNumber;
  49.  
  50. } // end while loop
  51.  
  52. } // end enterRecords function
  53.  
  54.  
  55.  
  56. // display single record
  57. void Tools::outputLine(ostream &output, const Tools &record )
  58. {
  59. output << left << setw(10 ) << record.getPartNumber()
  60. << setw( 16 ) << record.getToolName()
  61. << right << setw(9) << record.getInStock()
  62. << right << setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;
  63.  
  64. cout << left << setw(10) << record.getPartNumber()
  65. << setw( 16 ) << record.getToolName()
  66. << right << setw(12) << record.getInStock()
  67. << right<< setw(15) << setprecision(2) << fixed << showpoint << record.getUnitPrice() << endl;
  68. }
Last edited by QuantNeeds; Jul 28th, 2008 at 11:43 pm.
Attached Images
File Type: bmp screen.bmp (662.8 KB, 3 views)
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,662
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1501
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: printing text file string contents (array) - padded characters

 
0
  #6
Jul 29th, 2008
try clearing the string yourself before calling getline() and see if you still get the same results. I suspect it won't make any difference. That means the problem is something else in your program, such as something writing beyond the bounds of an array. If your program is still using that setToolName() function you posted earlier then that's the problem -- its not null-terminating the string. strncpy() doesn't null-terminate the string if the source string is longer than the destination buffer.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:




Views: 2181 | Replies: 5
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC