Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.06.2017, 20:00   #1
nightofpromises
Пользователь
 
Регистрация: 01.03.2017
Сообщений: 31
Сообщение Не читаемые символы при чтении файла из структуры "Товары"

У меня выводятся не читаемые символы на экран, когда я ввожу текст на русском: Снимок.JPG
В итоге в файл записываются какие-то непонятные мне символы: непонятные символы.JPG
Помогите мне, пожалуйста.
Вот исходный код программы:
Код:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
 
using namespace std;
 
struct TovarNaSklade
    {
    string nazvanietovara;
    double zakupochnayacena;
    double rozprice;
    double tovarnayanacenka;
    };
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_CTYPE, "Russian");
    const int n = 5;
    TovarNaSklade TovaryNaSklade[n];
    cout << "------------ Запись данных в файл ------------ \n";
    for(int i = 0; i < n; i++) 
    {
        cout << "Название товара: " << endl;
        cin >> TovaryNaSklade[i].nazvanietovara;
        cout << "Закупочная цена: " << endl;
        cin >> TovaryNaSklade[i].zakupochnayacena;
        cout << "Товарная наценка: " << endl;
        cin >> TovaryNaSklade[i].tovarnayanacenka;
        TovaryNaSklade[i].rozprice = TovaryNaSklade[i].zakupochnayacena * TovaryNaSklade[i].tovarnayanacenka * 0.01;
        cout << "\n";
     }
 
    double ucenka;
    cout << endl;
    cout << "Заданная цена: ";
    cin >> ucenka;
    for(int i = 0; i < n; i++)
    {
        if(TovaryNaSklade[i].rozprice > ucenka)
        {
            TovaryNaSklade[i].rozprice *= 0.8;
        }
    }
 
    // открытие файла для записи
    ofstream f1("C:\\Users\\User\\Downloads\\file1.txt",ios::binary|ios::out);
    if(!f1) // если файл не удалось создать, вывод сообщения об этом
    {
        cerr << "Файл не был создан. \n";
        return 0;
    }
    else // в противном случае
    {
        for (int i = 0; i < n; i++) // запись всех полей структуры в файл
        {
            f1.write(reinterpret_cast<char*>(&TovaryNaSklade[i]), sizeof(TovarNaSklade));
        }
    }
    f1.close(); // закрытие потока
 
    // открытие файла для чтения в двоичном формате
    ifstream f2("C:\\Users\\User\\Downloads\\file1.txt",ios::binary|ios::in);
    for (int i = 0; i < n; i++) // считываем данные в массив структур
        {
            f2.read(reinterpret_cast<char*>(&TovaryNaSklade[i]), sizeof(TovarNaSklade));
        }
    f2.close(); // закрытие потока
 
    cout << "------------ Считывание данных из файла ------------ \n";
    cout << "Товары в порядке возрастания розничной цены: " << endl;
    TovarNaSklade f;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < i - 1; j++)
        {
            if(TovaryNaSklade[j].rozprice > TovaryNaSklade[j + 1].rozprice)
            {
                f = TovaryNaSklade[j];
                TovaryNaSklade[j] = TovaryNaSklade[j + 1];
                TovaryNaSklade[j + 1] = f;
            }
        }
    }
    for(int i = 0; i < n; i++)
    {
        cout << "Название товара: \n" << TovaryNaSklade[i].nazvanietovara << endl;
        cout << "Закупочная цена: \n" << TovaryNaSklade[i].zakupochnayacena << endl;
        cout << "Товарная наценка: \n" << TovaryNaSklade[i].tovarnayanacenka << endl;
        cout << "Розничная цена: \n" << TovaryNaSklade[i].rozprice << endl;
    }
    system("pause");
    return 0;
}
А вот файл, в который записывается данная структура: file1.txt
nightofpromises вне форума Ответить с цитированием
Старый 20.06.2017, 23:47   #2
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Серьезно?

Код:
 f1.write(reinterpret_cast<char*>(&TovaryNaSklade[i]), sizeof(TovarNaSklade));

Так нельзя делать с объектами, коим является std::string nazvanietovara

И читать его обратно тоже нельзя, как у вас - это все мусор будет, с адресами. Что значит, на другом компе будет не верный адрес и все вообще взорвется при чтении файла.

Более того, сам способ так записывать гавно. Т.к. у структур есть выравнивания, т.е. на 64 бита системе (8 байт) скажем структура занимает 17 байт "почтучно", но реально она займет в памяти 24 байта (ближайшее кратное). И вот у вас уже запись-чтение не совсем верно. Потом вы этот файл несете на 32-бита машину, там реальный размер 20 байт, и все вообще взорвалось. Если уж приспичило, нужно указывать параметры компиляции и задавать фиксированое выравнивание, скажем 4 байта (как это на VC не знаю, это не стандарт).

Т.е. я хочу сказать - оптом всю структуру писать и читать крайне плохая идея. И два - постарайтесь не использовать reinterpret_cast ближайшие полгода, этой командой вы шлете компилятор в пешее эротическое со всеми его предупреждениями, и он позволяет вам отстрелить себе ногу (а вот в тему дискуссия: http://www.programmersforum.ru/showt...=143908&page=5)

Последний раз редактировалось alexzk; 21.06.2017 в 14:23.
alexzk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
0xC0000005: Нарушение прав доступа при чтении "0x00000088" ninja2 Visual C++ 9 17.08.2015 22:47
Фильтровать товары при "бесконечной" прокрутке MrBrain JavaScript, Ajax 4 29.09.2012 22:48
Отфильтровать Метаэлементы "." и ".." при чтении каталога Armatus PHP 1 14.05.2012 15:35
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04