2014-11-20 2 views
0

Я пишу программу для хранения данных инвентаризации в двоичном текстовом файле. Одной из функций является поиск имени элемента (который уже был введен) в текстовом файле, и если он найден, прочитайте информацию в структуре, обновите ее и отправьте структуру обратно в файл.Обновление информации в двоичном текстовом файле с помощью struct (C++)

Проблема заключается в использовании seekp/seekg для перезаписи правильных данных. I.E. Структура содержит имя элемента, общий запас, оптовую цену и розничную цену. Но мой текущий код будет только перезаписывать имя элемента при отправке обратно в текстовый файл.

У меня такое чувство, что это связано с неправильным использованием поиска/чтения/записи. В следующем коде я использую только одну структуру для временного хранения данных при вводе/выводе в файл. (Я ненавижу сбросить код, как это, но я не уверен, что еще делать в этой точке.) Ниже приводится функция для изменения определенного элемента, который уже был введен:

Структура

struct inventory 
{ 
    string itemname; 
    int stock; 
    double costWS, 
      costRE; 
}; 

, но я создал только один «держатель», который можно использовать при добавлении элементов в текстовый файл или поиск/изменение элементов.

void ModifyRecord() 
{ 
    fstream update ("Records.txt" , ios::in|ios::ate|ios::binary); 
    bool found = false; 
    long int whereAmI; 
    string tomodify; 
    cout << "Enter the name of the item to modify." << endl; 
    cin >> tomodify; 

    while (!update.eof() || !found ) 
    { 
     //holder is the structure containing inventory data 
     //this will read only one structure at a time, to send to holder 
     update.read(reinterpret_cast<char *> (&holder), sizeof(holder)); 
     cout << "Reading new struct." << endl; 
     whereAmI = update.tellg();//save input position 
     //check this structure for the name entered 
     if (holder.itemname.find(tomodify) == 0) 
     { 
      found = true;//exit while loop 
      update.seekg(-(sizeof(holder)), ios::cur); 
      //Update data 
      cout << "String found. \nYou have selected to modify: " 
       << holder.itemname << endl; 
     cout << "Enter new name for the item: " << endl; 
     cin >> holder.itemname; 
     do 
     { 
      cout << "Enter amount stocked." << endl; 
      cin >> holder.stock; 
     }while(holder.stock < 0); 

     do 
     { 
      cout << "Enter wholesale cost." << endl; 
      cin >> holder.costWS; 
     }while(holder.costWS < 0); 

     do 
     { 
      cout << "Enter retail cost." << endl; 
      cin >> holder.costRE; 
     }while(holder.costRE < 0); 

     //send back to file 

     update.write(reinterpret_cast<char *> (&holder), sizeof(holder)); 
     whereAmI = update.tellp();//save current output position 
     update.close(); 
     break; 
    } 
} 
if (!found) 
    cout << "Keyword not found." << endl; 
} 

Так как я могу переписать правильные данные с помощью seekg/p? Правильно ли я использую чтение/запись?

ответ

0

Первый: «бинарный текстовый файл» звучит как «холодная горячая вода». Вы должны решить: хотите ли вы работать с двоичным кодом или текст файл.

Второй: Ваша структура inventory содержит поле типа string, поэтому он не может быть использован как POD, но вы пытаетесь сделать это:

update.seekg(-(sizeof(holder)), ios::cur); 
       ^^^^^^^^^^^^^^ 

и

update.write(reinterpret_cast<char *> (&holder), sizeof(holder)); 
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ 

Third: Если вы измените свою структуру следующим образом:

struct inventory { 
    enum { MAX_ITEM_LENGTH = 100 }; 
    char itemname[ MAX_ITEM_LENGTH + 1 ]; // +1 for trailing '\0' 
    int stock; 
    double costWS, 
      costRE; 
}; 

, то алгоритм будет выглядеть так:

fstream update ("Records.txt" , ios::in|ios::ate|ios::binary); 
bool found = false; 
string tomodify; 
cout << "Enter the name of the item to modify." << endl; 
cin >> tomodify; 
while (!update.eof()) 
{ 
    update.read(reinterpret_cast<char *> (&holder), sizeof(holder)); 
    if (tomodify == holder.itemname) 
    { 
     update.seekg(-(sizeof(holder)), ios::cur); 
     cout << "String found. \nYou have selected to modify: " 
      << holder.itemname << endl; 
     cout << "Enter new name for the item: " << endl; 
     string newItemName; 
     cin >> newItemName; 
     strncpy(holder.itemname, newItemName.c_str(), inventory::MAX_ITEM_LENGTH); 
     do 
     { 
      cout << "Enter amount stocked." << endl; 
      cin >> holder.stock; 
     } while(holder.stock < 0); 
     do 
     { 
      cout << "Enter wholesale cost." << endl; 
      cin >> holder.costWS; 
     } while(holder.costWS < 0); 
     do 
     { 
      cout << "Enter retail cost." << endl; 
      cin >> holder.costRE; 
     } while(holder.costRE < 0); 
     //send back to file 
     update.write(reinterpret_cast<char *> (&holder), sizeof(holder)); 
     found = true; 
     break; 
    } 
} 
if (!found) 
    cout << "Keyword not found." << endl; 
} 
Смежные вопросы