您试图完成一些代码并遇到问题。我的程序试图将记录写入二进制文件,然后在调用适当的函数时将其读回。每当我尝试将文件读入动态数组以便我可以格式化输出时,只有垃圾值(我认为地址?)打印在第一个文本之后。
这是我现在正在使用的代码,
#include <iostream>
#include<iomanip>
#include <fstream>
using namespace std;
struct Inventory
{
char desc[30];
int qty;
double wholeSaleCost;
};
// Function prototypes
void addRecord(fstream &);
void viewRecord(fstream &);
void changeRecord(fstream &);
bool validInput(char userInput);
// This function will add a record to the file
void addRecord(fstream &inventoryFile)
{
Inventory recordUserInput;
cin.ignore();
char *tempWholeSale;
char *tempQuantity;
tempWholeSale = new char[sizeof(Inventory().wholeSaleCost)];
tempQuantity = new char[sizeof(Inventory().qty)];
cout << "Enter the following inventory data:" << endl;
cout << "Description: ";
cin.getline(recordUserInput.desc, sizeof(Inventory().desc));
cout << endl;
cout << "Quantity: ";
cin.getline(tempQuantity, sizeof(Inventory().qty));
while (!validInput(*tempQuantity))
{
cout << "That is not a valid input, please enter a number greater than 0." << endl;
cout << "Quantity: ";
cin.getline(tempQuantity, sizeof(Inventory().qty));
}
recordUserInput.qty = atoi(tempQuantity);
cout << endl;
cout << "Retail Price: ";
cin.getline(tempWholeSale, sizeof(Inventory().wholeSaleCost));
while (!validInput(*tempWholeSale))
{
cout << "That is not a valid input, please enter a number greater than 0." << endl;
cout << "Retail Price: ";
cin.getline(tempWholeSale, sizeof(Inventory().wholeSaleCost));
}
recordUserInput.wholeSaleCost = atof(tempWholeSale);
cout << endl;
// Adding record to the end of a binary file
inventoryFile.open("C:/temp/inventory.dat", ios::out | ios::app | ios::binary);
if (inventoryFile)
{
inventoryFile.write(reinterpret_cast<const char*>(&recordUserInput.desc), sizeof(Inventory().desc));
inventoryFile.write(reinterpret_cast<const char*>(&recordUserInput.qty), sizeof(Inventory().qty));
inventoryFile.write(reinterpret_cast<const char*>(&recordUserInput.wholeSaleCost), sizeof(Inventory().wholeSaleCost));
inventoryFile.close();
}
else
{
cout << "File Failed to open." << endl;
}
}
void viewRecord(fstream &inventoryFile)
{
int recordNumber;
char * recordReadFromFile;
int recordIterator = 0;
recordReadFromFile = new char[sizeof(Inventory)];
cout << "Enter the record number of the item: ";
cin >> recordNumber;
cin.ignore();
cout << endl;
// Reading from file
inventoryFile.open("C:/temp/inventory.dat", ios::in | ios::binary);
if (inventoryFile)
{
inventoryFile.seekg((sizeof(Inventory)*recordNumber), ios::beg);
inventoryFile.read(recordReadFromFile, sizeof(Inventory));
inventoryFile.close();
}
else
{
cout << "File Failed to open." << endl;
}
//Record Display
cout << "Description: ";
for (recordIterator; recordIterator < 32; )
{
cout << recordReadFromFile[recordIterator];
recordIterator++;
}
cout << endl << "Quantity: ";
for (recordIterator; recordIterator < 38; )
{
cout << recordReadFromFile[recordIterator];
recordIterator++;
}
cout << endl << "Retail Price: ";
for (recordIterator; recordIterator < 48; )
{
cout << recordReadFromFile[recordIterator];
recordIterator++;
}
}
Main只有一个if / else块来调用不同的函数。我正在使用的fstream对象是&f; fstream inventoryFile&#39;
cout显示的数字来自使用sizeof(Inventory.desc)等,我发现inv.desc是30个字节,.qty是4个字节而.wholeSale是8个字节(预期)但是我可以&# 39;在单独编写每个结构成员时找到解决缓冲区问题的方法。非常感谢任何可以提供的帮助,通过这两个问题使我陷入停滞。
答案 0 :(得分:0)
尝试更像这样的事情:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <sstream>
#include <limits>
#pragma pack(push, 1) // or your compiler's equivilent...
struct Inventory
{
char desc[30];
int qty;
double wholeSaleCost;
};
#pragma pack(pop)
// Function prototypes
void addRecord();
void viewRecord();
void changeRecord();
void resetInput()
{
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
}
template<typename T>
void promptforNumber(const char *prompt, T &value)
{
do
{
std::cout << prompt << ": ";
if (std::cin >> value)
{
if (value >= T(0))
break;
std::cout << "Please enter a number greater than or equal to 0." << std::endl;
}
else
{
resetInput();
std::cout << "That is not a valid number, please try again." << std::endl;
}
}
while (true);
}
void promptforRecordData(Inventory &item)
{
std::cout << "Enter the following inventory data:" << endl;
do
{
std::cout << "Description: ";
if (std::cin.getline(item.desc, sizeof(item.desc)))
break;
resetInput();
std::cout << "Please enter a string less than " << sizeof(item.desc) << " chars." << std::endl;
}
while (true);
std::cout << std::endl;
promptforNumber("Quantity", item.qty);
std::cout << std::endl;
promptforNumber("Retail Price", item.wholeSaleCost);
std::cout << std::endl;
}
void displayRecord(const Inventory &item)
{
std::cout << "Description: " << item.desc << std::endl;
std::cout << "Quantity: " << item.qty << std::endl;
std::cout << "Retail Price: " << item.wholeSaleCost << std::end;
}
bool readRecord(std::istream &in, Inventory &item)
{
if (!in.read(reinterpret_cast<char*>(&item), sizeof(item)))
std::cout << "Failed to read inventory item." << std::endl;
return in.good();
}
bool writeRecord(std::ostream &out, const Inventory &item)
{
if (!out.write(reinterpret_cast<const char*>(&item), sizeof(item)))
std::cout << "Failed to write inventory item." << std::endl;
return out.good();
}
bool seekInToRecord(std::istream &in, int recordNumber)
{
if (!in.seekg(sizeof(Inventory) * recordNumber))
std::cout << "Failed to seek file." << std::endl;
return in.good();
}
bool seekOutToRecord(std::ostream &out, int recordNumber)
{
if (!out.seekp(sizeof(Inventory) * recordNumber))
std::cout << "File Failed to seek." << std::endl;
return out.good();
}
// This function will add a record to the file
void addRecord()
{
Inventory inventoryItem;
promptforRecordData(inventoryItem);
// Adding record to the end of a binary file
std::ofstream inventoryFile("C:/temp/inventory.dat", std::ios::app | ios::binary);
if (!inventoryFile.is_open())
{
std::cout << "Failed to open file." << std::endl;
return;
}
writeRecord(inventoryFile, inventoryItem);
}
// This function will display a record from the file
void viewRecord()
{
int recordNumber;
promptForNumber("Enter the record number of the item", recordNumber);
std::cout << endl;
// Reading from file
std::ifstream inventoryFile("C:/temp/inventory.dat", std::ios::binary);
if (!inventoryFile.is_open())
{
std::cout << "Failed to open file." << std::endl;
return;
}
if (recordNumber > 0)
{
if (!seekInToRecord(inventoryFile, recordNumber))
return;
}
Inventory inventoryItem;
if (!readRecord(inventoryFile, inventoryItem))
return;
inventoryFile.close();
//Record Display
displayRecord(inventoryItem);
}
// This function will change a record in the file
void changeRecord()
{
int recordNumber;
promptForNumber("Enter the record number of the item", recordNumber);
std::cout << endl;
// Reading from file
std::fstream inventoryFile("C:/temp/inventory.dat", std::ios::in | std::ios::out | std::ios::binary);
if (!inventoryFile.is_open())
{
std::cout << "File Failed to open." << std::endl;
return;
}
if (recordNumber > 0)
{
if (!seekInToRecord(inventoryFile, recordNumber))
return;
}
Inventory inventoryItem;
if (!readRecord(inventoryFile, inventoryItem))
return;
//Record Display
displayRecord(inventoryItem);
// Overwrite record in binary file
promptForRecordData(inventoryItem);
if (seekOutToRecord(inventoryFile, recordNumber))
writeRecord(inventoryFile, inventoryItem);
}