Как исправить ошибку синтаксиса ifstream и возможную потерю ошибки преобразования данных в C ++? - PullRequest
0 голосов
/ 24 марта 2019

У меня есть код из файла Source.cpp для моего кода. Я нахожусь в середине этой лаборатории, в которой я создаю инвентарь, который отслеживает магазин камеры. Это почти завершено, но у меня ошибка C4244 (возможная потеря данных при использовании = on вроде 24) и ошибка C3867 (ios :: base_fail / ios :: basic_ifstream). Я напишу "ЗДЕСЬ" рядом с тем, где возникла ошибка, так как я не могу сказать вам, какая строка. Вот этот код:

#include<iostream>
#include<string>
#include<fstream>
#include "LinkedList.h"
using namespace std;

int main()
{
LinkedList ll; // Creating object of linked list

struct info record;

char dataToBeRead[100];

ifstream fp; 

fp.open("fileInventory.txt");

if (fp.fail) !!!HERE!!! 
{
    cout << "The file cannot be opened\n";
}
else


{
    while (fp.open, dataToBeRead[100] != NULL) !!!HERE!!!
    {
        char *token = strtok(dataToBeRead, " "); 
        strcpy(record.camera, token); 
        token = strtok(NULL, " ");
        record.price = atof(token);
        token = strtok(NULL, " ");
        record.quantity1 = atoi(token); !!!HERE!!! (possible loss of data?)
        token = strtok(NULL, " ");
        record.quantity2 = atoi(token);
        token = strtok(NULL, " ");
        ll.addEnd(record);
        ll.addReverse(record);

    }
    int ch = 0;
    char camera[50];
    float price;
    int quantity1;
    int quantity2;
    do //Must open the menu
    {
        cout << "1. Display the inventory in alphabetic order:\n";
        cout << "2. Display the inventory in reverse alphabetic order:\n";
        cout << "3. Add an item to the inventory:\n";
        cout << "4. Delete an item from inventory:\n";
        cout << "5. Change any info for an item:\n";
        cout << "6. Exit:\n";
        cin >> ch;
        switch (ch)
        {
        case 1:
            ll.showList1();
            break;
        case 2:
            ll.showList2();
            break;
        case 3:
            cout << "Enter camera:\n";
            cin >> camera;
            cout << "Enter price:\n";
            cin >> price;
            cout << "Enter quantity1:\n";
            cin >> quantity1;
            cout << "Enter quantity2:\n";
            cin >> quantity2;
            strcpy(record.camera, camera);
            record.price = price;
            record.quantity1 = quantity1;
            record.quantity2 = quantity2;
            ll.addEnd(record);
            ll.addReverse(record);
            ll.showList1();
            ll.showList2();
            break;
        case 4:
            cout << "Enter camera name to be deleted:\n";
            cin >> camera;
            ll.removeValue1(camera);
            ll.removeValue2(camera);
            ll.showList1();
            ll.showList2();
            break;
        case 5:
            cout << "Enter the camera name for which you want to edit details:\n";
            cin >> camera;
            cout << "Enter price:\n";
            cin >> price;
            cout << "Enter quantity1:\n";
            cin >> quantity1;
            cout << "Enter quantity2:\n";
            cin >> quantity2;
            ll.editList(camera, price, quantity1, quantity2);
            break;
        case 6:
            break;

        }
    } while (ch != 6); // Menu will run until the ch is not 6


    ofstream myfile;
    myfile.open("newlist.txt"); 

    if (myfile.fail) !!!HERE!!!
    {
        exit(1);
    }

}

return 1;
}

Это явно проблема с fstream, но я не знаю, что я делаю неправильно. И я не уверен, почему возможна потеря данных именно по этой линии. Заранее благодарю за помощь!

1 Ответ

1 голос
/ 24 марта 2019

Излишне говорить, что эта строка:

while (fp.open, dataToBeRead[100] != NULL)

неверна.

Кроме того, чтобы проверить, успешно открыт файл или нет, вы можете просто сделать это:

if (!fp)
{
    // file failed to open
}

Но в целом, самый простой способ - вообще не вводить массивы символов, а вместо этогоиспользуйте std::string:

  std::string dataToBeRead;
  while (std::getline(fp, dataToBeRead)) 
  {
   //...
  }

Учитывая, что dataToBeRead теперь является std::string, логика токенизации должна измениться.Это просто делается с помощью std :: istringstream и использованием operator >>.

std::istringstream strm(dataToBeRead);
strm >> record.camera >> record.price >> record.quantity1 >> record.quantity2;
ll.addEnd(record);
ll.addReverse(record);

Таким образом, весь цикл выглядит так:

  #include <sstream>
  //...
  std::string dataToBeRead;
  while (std::getline(fp, dataToBeRead)) 
  {
     std::istringstream strm(dataToBeRead);
     strm >> record.camera >> record.price >> record.quantity1 >> record.quantity2;
     ll.addEnd(record);
     ll.addReverse(record);
  }

Это далекопроще и безопаснее, чем при обработке в стиле C strtok.


Вы также можете пропустить все создание строки, непосредственно прочитав ввод, используя operator >>:

  while (fp >> record.camera >> record.price >> record.quantity1 >> record.quantity2)
  {
     ll.addEnd(record);
     ll.addReverse(record);
  }

Обычно вы хотите использовать этот метод, если анализ данных прост (в вашем случае они разделяются пробелами).Если что-то более сложное, чем это, то можно использовать istringstream.

...