C++库存项目移除

C++ inventory item removal

本文关键字:项目 C++      更新时间:2023-10-16
  • 将库存增加到 10 件。做!!!
  • 创建一个 for 循环,要求用户输入清单中的初始物料。做!!!
  • 在 for 循环之后创建一个小故事,治疗师在其中更改两个项目(即项目 4 和 8)。我想要的是将一个项目交换为另一个项目,即您想将您的 {[项目] 换成 [item2] y 或 n
  • 按字母顺序对清单进行排序。 如果需要,您可以使用自己的排序,但这里有一个气泡排序算法:

 

// A simple inventory program using a struct to store data
// in an array.

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
// define a data structure
struct InventoryRecord
{
  string name;   // inventory item name
  int qty;       // how many are in stock
  double value;   // the value
};
// const for the max size of the record array
const int MAX_SIZE = 9;
// function prototypes
void addData(InventoryRecord list[], int& size);
void dispData(const InventoryRecord list[], int size);
void remData( const InventoryRecord list[], int size);
void saveFile(const InventoryRecord list[], int size);
void openFile(InventoryRecord list[], int& size);
char getMenuResponse();

int main(int argc, char *argv[])
{
  InventoryRecord recList[MAX_SIZE];
  int numOfRecs = 0;
  bool run = true;
  do
  {
    cout << "Hero's Inventory - " << numOfRecs << " items in your bag" << endl;
    switch ( getMenuResponse() ) 
    {
        case 'A': addData(recList, numOfRecs); break; 
        case 'D': dispData(recList, numOfRecs); break;
        case 'R': remData(recList, numOfRecs); break;
        case 'O': openFile(recList, numOfRecs); break;
        case 'S': saveFile(recList, numOfRecs); break;
        case 'Q': run = false; break;
        default : cout << "That is NOT a valid choice" << endl;
    }
  } while (run);
  cout << endl << "Program Terminated" << endl;
  // system("PAUSE"); // Program exits immediatly upon "Quit" if commented out
  return EXIT_SUCCESS;
}
// Task:     Allow data entry of one inventory item
// Accepts:  References to the inventory array and its size
// Returns:  Nothing
// Modifies: The array and size 'actual parameter'
// NOTE:     Could be modified to allow entry of more than one item
void addData(InventoryRecord list[], int& size)
{
  InventoryRecord tmp; // declare a temp item that we will load before putting in the array
  char response;
  char str[256]; // needed for cin.getline; we are going to use a char array
  if (size < MAX_SIZE) {
    system("cls");
    cout << "Please enter 10 items helpful to your quest! " << endl;
    cout << "Enter item: " << endl << endl;
    cout << "Name:     ";
    // Get up to 256 characters from the keyboard including white space.
    // Stop reading if encounter the n first. If there's any chance of 
    // more than 256 characters you will have to clean up cin with
    // cin.ignore before the next input.
    cin.getline(str, 256, 'n'); // for char arrays; different from the other getline
    tmp.name = str;
    cout << "Quantity: ";
    cin >> tmp.qty;
    cout << "Value:     ";
    cin >> tmp.value;
    cout << endl;
    // see if this record should be added to the array
    cout << "Add to inventory? (y/n) ";
    cin >> response;
    if (toupper(response) == 'Y') 
      list[size++] = tmp;
  } else {
    cout << "Inventory is full; cannot enter more units." << endl;
    system("pause");
  }
  system("cls");
}
void dispData(const InventoryRecord list[], int size)
{
  system("cls");
  double cost = 0;
  if(size < 1) {
    cout << "Nothing to display" << endl;
  } else {
    cout << "All Items in your Bag" << endl << endl;
    cout << fixed << setprecision(2);   
    cout << "Item Name              Qty     Value" << endl;
    cout << "~~~~~~~~~~~~~~~~~~" << endl;
    cout << left;     
    for (int i = 0; i < size; i++) {
      cout << setw(21) << list[i].name << right
           << setw(4)  << list[i].qty
           << setw(10) << list[i].value << left << endl;
           cost = cost + list[i].value * list[i].qty;
    }
    cout << "~~~~~~~~~~~~~~~~~~~" << endl;
    cout << right << setw(3) << size;
    cout << " items listed";
    cout << right << setw(19) << cost << endl << endl;
  }
  system("PAUSE");
  system("cls");
}
void remData(const InventoryRecord list[], int size) {
    system("cls");
    cout <<"Enter Item you wish to remove from your inventory: " << endl;// This is being displayed so user can see items in the inventory
    double cost = 0;
  if(size < 1) {
    cout << "Nothing to display" << endl;
  } else {
    cout << "All Items in your Bag" << endl << endl;
    cout << fixed << setprecision(2);   
    cout << "Item Name              Qty     Value" << endl;// It is not displaying right the alignment is off
    cout << "~~~~~~~~~~~~~~~~~~" << endl;
    cout <<"Item Name: ";/* from here I do not know what to do! What I want is have use type the item name they want removed
                            also display an error if they enter an  item wrong*/
    cout << left;     
    for (int i = 0; i < size; i++) {
      cout << setw(21) << list[i].name << right
           << setw(4)  << list[i].qty
           << setw(10) << list[i].value << left << endl;
           cost = cost + list[i].value * list[i].qty;
    }
    cout << "~~~~~~~~~~~~~~~~~~~" << endl;
    cout << right << setw(3) << size;
    cout << " items listed";
    cout << right << setw(19) << cost << endl << endl;
  }}
// Save records to disc
void saveFile(const InventoryRecord list[], int size) {
  ofstream outfi("Inventory.txt");
  // make sure the file stream is open before doing IO
  if (!outfi.fail()) { 
    system("cls");  
    cout << "Saving inventory to the disc ";
    for(int i = 0; i < size; i++) {
      outfi << list[i].name << ';' 
            << list[i].qty << ';'
            << list[i].value;
      // Start a new line after all but the last record
      // Simplifies reading the file as EOF is at end of last line
      if (i < size-1) outfi << endl;
    }
    cout << endl << size << " records writen to the disc." << endl;
    outfi.close();
    system("PAUSE");
    system("cls");
  } 
  else {
    cout << "ERROR: problem with file" << endl;
    system("PAUSE");
    system("cls");
  }
}
// Open file and load array
void openFile(InventoryRecord list[], int& size)
{
  ifstream infi("Inventory.txt");
  string str;
  stringstream strstrm;
  // make sure the file stream is open before doing IO
  if (!infi.fail()) { 
    system("cls");
    cout << "Reading inventory from the disc ";
    size = 0; // overwrite any existing records
    while(!infi.eof() && size < MAX_SIZE) {
      // get and store the name
      getline(infi, str, ';'); 
      list[size].name = str;
      // get, convert and store the quantity
      getline(infi, str, ';');
      strstrm.str(""); strstrm.clear(); // empty and clear the stringstream
      strstrm << str; 
      strstrm >> list[size].qty;
      // get, convert and store the cost
      getline(infi, str); 
      strstrm.str(""); strstrm.clear(); // empty and clear the stringstream
      strstrm << str; 
      strstrm >> list[size++].value;
    }
    cout << endl << size << " records read from the disc." << endl;
    system("PAUSE");
    system("cls");
  }
  else { // something went wrong with opening the file
    cout << "ERROR: problem with file" << endl;
    system("PAUSE");
    system("cls");
  }
}
char getMenuResponse()
// Task:     Put the menu on screen and get a response
// Accepts:  Nothing
// Returns:  The users response
// Modifies: Nothing
// NOTE:     Characters are far more intuitive at the command
//           line than numbers; avoid using numbers.
{
    char response;
    cout << endl << "Make your selection" << endl
         << "(A)dd Items, (D)isplay Items, (R)emove items, (O)pen File, (S)ave File, (Q)uit" << endl
         << "> ";
    cin >> response;
    cin.ignore(256, 'n');  
    // clean-up up to 256 chars including the delimiter specified (n, the endl) 
    // OR stop when the n is encountered after removing it.
    return toupper(response);
}

要从清单中删除元素,您只需将已删除元素后的所有元素向前移动一个位置。完成此操作后,您还需要将冗长的时间减少一个。例如,从具有当前length元素的数组中删除位置index的元素 array

您可以使用
if (index < length) {
    std::copy(array + index + 1, array + length, array + index);
    ++length;
}

基本上有两种方法可以删除元素,最简单的方法是将要删除的元素与最后一个元素交换并调整列表大小:

void deleteElem(Data[] list, int & listLength, int ix) {
    if (ix < listLength - 1) {
        list[ix] = list[listLength - 1];
    }
    --listLength;
}

第二个解决方案是在删除左侧元素 1 之后的 memmove everthing:

void deleteElem(Data[] list, int & listLength, int ix) {
    memmove(list[ix], list[ix + 1], (listLength - ix - 1) * sizeof(Data));
    --listLength;
}

编辑:内存移动的长度有错误,总是相同的。您应该阅读文档。