Pasar una Cola(Queue) a un Archivo (Guardar y sobreescribir) C++

El proyecto está en CodeBlocks, no sé mucho de programación pero quiero aprender más sobre c++ y su potencial que tiene.

Cola.h

#ifndef COLA_H_INCLUDED
#define COLA_H_INCLUDED
/*Practice No. 4: Queue */
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;

template <typename T>
class Cola {

private:
    class Nodo {
    public:
        T dato;
        Nodo* siguiente;
    };
    Nodo* nuevo;
    Nodo* inicio;
    Nodo* fin; //fondo
public:
    Cola();
    ~Cola();

    void insertar();
    int extraer();
    void imprimir();
    bool vacia();
};

/*************Constructor,destructor********/
template <typename T>
Cola<T>::Cola()
{
    inicio = NULL;
    fin = NULL;
}

template <typename T>
Cola<T>::~Cola()
{
    Nodo* recorrido = inicio;
    Nodo* bor;
    while (recorrido != NULL) {
        bor = recorrido;
        recorrido = recorrido->siguiente;
        delete bor;
    }
}

/*************Métodos (Funciones)***********/
template <typename T>
void Cola<T>::insertar()
{
    T x;

    nuevo = new Nodo();

    cout << "Dato a ingresar: ";
    getline(cin, x);
    getline(cin, x);
    //cin>>x;

    nuevo->dato = x;
    nuevo->siguiente = NULL;
    if (vacia()) {
        inicio = nuevo;
        fin = nuevo;
    }
    else {
        fin->siguiente = nuevo;
        fin = nuevo;
    }
}

template <typename T>
int Cola<T>::extraer()
{
    if (!vacia()) {
        string informacion = inicio->dato;
        Nodo* bor = inicio;
        if (inicio == fin) {
            inicio = NULL;
            fin = NULL;
        }
        else {
            inicio = inicio->siguiente;
        }
        cout << "Dato eliminado, ahora el dato a quitar  es:" << inicio->dato << endl;
        delete bor;
        //return informacion;
    }
    else {
        cout << endl
             << "Empty Queue!!!" << endl;
        //return -1;
    }
}

template <typename T>
void Cola<T>::imprimir()
{
    Nodo* recorrido = inicio;
    cout << "Listado de todos los elementos de la cola." << endl;
    while (recorrido != NULL) {
        cout << "|" << recorrido->dato << "|"
             << "-";
        recorrido = recorrido->siguiente;
    }
    cout << endl;
}

template <typename T>
bool Cola<T>::vacia()
{
    if (inicio == NULL)
        return true;
    else
        return false;
}
#endif // COLA_H_INCLUDED

main.cpp

#include <iostream>
#include "cola.h"
#include "portada.h"
#include <cstdlib>
#include <conio.h>
using namespace std;

int main()
{
    portada();

    Cola<string> C;

    /************* Menu ***********/
    bool flag = false;
    char tecla;
    char answer[2];

    do {
        system("cls");
        cin.clear();

        cout << "\t***Queue:Elige una opcion***" << endl
             << "\t1)Insertar" << endl
             << "\t2)Quitar" << endl
             << "\t3)Mostrar Queue" << endl
             << "\t4)Salir" << endl;
        cin >> tecla;

        switch (tecla) {
        case '1':
            cout << endl
                 << "Opcion 1)Insertar<" << endl;
            C.insertar();
            system("pause");
            break;

        case '2':
            cout << endl
                 << "Opcion 2)Eliminar<" << endl;
            do {

                cout << "\aDesea quitar mas datos?? s/n: ";
                cin >> answer[2];
                if ((answer[2] == 'S') || (answer[2] == 's')) {
                    cout << endl;
                    C.extraer();
                    //delete C;
                }

            } while (answer[2] == 'S' || answer[2] == 's');

            system("pause");
            break;

        case '3':
            cout << endl
                 << "Opcion 3)to Show<" << endl;
            C.imprimir();
            system("pause");
            break;
        case '4':
            C.~Cola();
            cout << endl
                 << "\a\aHasta la vista baby :-3 " << endl;
            flag = true;
            break;
        }
    } while (flag != true);
    getch();
    return 0;
}
1
задан 24.10.2016, 17:59
3 ответа

У меня не остается очень ясным, что ты нуждаешься, но я понимаю, что ты хочешь, что твой класс шаблон Cola смогите переворачиваться в файл:

Перемещать Очередь (Queue) в Файл (Сохранять и sobreescribir)

То, что у меня не остается ясным, если ты хочешь, чтобы эта функциональность принадлежала в Cola или внешний независимый класс взялся за это; так что я выберу самое гибкое решение, и осуществление прокручивает изображение в окне твоего счета.

Оформи нотариальным актом в файле основная.

Чтобы переворачивать контент в файл ты будешь должен создавать один stream файла (fstream или filestream) или один stream вывода файла (ofstream или output filestream); stream они располагают оператором вставки operator << что позволяет делать инъекцию данным с форматом.

Следующий пример показывает, как сохранять целое число в файле используя stream вывода файла:

std::ofstream salida("mi_archivo.txt");

if (salida.is_open())
{
    salida << 0xffffffffu;
}

Предыдущий пример сохраняет самое большее положительное перепредставительное число из-за 32 бит в так называемом файле mi_archivo.txt, если файл существовал заблаговременно это на - escribirá, в противоположном случае он это создаст.

Если мы пойдем в каталог выполнения нашей программы, мы увидим, что упомянутый файл существует, и Ваш контент был бы:

4294967295

Что является, действительно, самым большим положительным перепредставительным числом из-за 32 бит, которое сохраняло как цепь текста. Возможно вместо того, чтобы, на писать, предпочти сохранять предыдущий контент файла; это ты будешь должен определять это во время создания stream:

std::ofstream salida("mi_archivo.txt", std::fstream f1("test.bin", std::ios::app);

if (salida.is_open())
{
    salida << 0xfabadau;
}

Предыдущий код открывается mi_archivo.txt и помести указатель написания в конце файла, его получают, произойдя с ним как второй параметр std::ios::app, что значит append (присоединять).

Таким образом сохраняются данные, которые существовали заблаговременно. Открыв файл мы будем видеть:

429496729516431834

Что главным образом стоимости 4.294.967.295 (0xffffffffu) и seguidamente стоимость 16.431.834 (0xfabadau); если бы мы не узнали того, что мы написали, мы увидели бы группу бессмысленных чисел и еще зная то, что мы написали, мы не знаем, число ли это очень grande1, несколько сцепленных чисел или выигрывающая комбинация лотереи Солнечной Системы, так что лучшее будет состоять в том, чтобы добавлять разделитель между информацией и информацией:

std::ofstream salida("mi_archivo.txt", std::fstream f1("test.bin", std::ios::app);

if (salida.is_open())
{
    salida << ',' << 0xcafe5010u;
}

С предыдущим кодом, перед тем, как писать число, мы добавляем запятую, чтобы отделять новую информацию о предыдущих данных, открыв файл, мы видели бы:

429496729516431834,3405664272

После запятой себе показывает стоимость 3.405.664.272 (0xcafe5010u).

Оформи нотариальным актом в файле передовой пост.

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

std::ofstream salida("mi_archivo.txt", std::ios::binary);

if (salida.is_open())
{
    unsigned int ffffffffu = 0xffffffffu;
    salida.write(reinterpret_cast<char *>(&ffffffffu), sizeof(ffffffffu));
}

Второй параметр показывает ему в файл, что Ваш способ открытия будет бинарным. Функция бинарного написания получает указатель в характер (char *) и количество символов, которое нужно писать; поэтому мы нуждались в том, чтобы повторно интерпретировать информацию, которую нужно писать, чтобы это перемещать в вышеупомянутую функцию. Инструкция write примера говори: напиши binariamente в файле, манипулируемом из-за salida контент указанного из-за первого параметра до acanzar количество байт, показанное вторым параметром. Возможно, что, открыв файл, произведенный предыдущим кодом, ты видишь следующее:

����

Что достаточно непонятное, я советую тебе, чтобы ты загрузил шестнадцатеричный редактор, чтобы видеть контент файла, который конечно будет нечто похожим:

FFFFFFFF

Возможно сочетать бинарное написание с написанием в конце файла:

std::ofstream salida("mi_archivo.txt", std::fstream f1("test.bin", std::ios::app | std::ios::binary);

if (salida.is_open())
{
    unsigned int fabadau = 0xfabadau;
    salida.write(reinterpret_cast<char *>(&fabadau), sizeof(fabadau));
}

Второй параметр - комбинация манеры присоединять и бинарного способа. Открыв файл с редактором exadecimal мы будем видеть

FFFFFFFFFABADA00

Или возможно

FFFFFFFF00DABAFA

Согласно краю системы, в которой ты выполняешь программу.

Преимущества в том, чтобы сохранять в бинарном звуке:

  • Ты можешь обходиться часто без разделителей: уже ты знаешь то, что занимает каждую информацию (все типы int они занимают 4 байт, по крайней мере в той же архитектуре).
  • Займи меньше: цепь 4294967295 займи 10 байт, но то же число в бинарном занимает 4.

Невыгоды сохранения в бинарном звуке:

  • Он не является читабельным из-за человека: что затрудняет интерпретировать или отлаживать контент.
  • Ваше написание и чтение менее интуитивное: использованные методы могут быть более перегруженными.
  • Бинарный формат между платформами может меняться: край данных и размер типов могут быть несовместимыми между какими-то платформами.

У тебя есть другая проблема.

Твой класс Cola это шаблон, который сохраняет произвольные данные о типе T:

template <typename T>
class Cola {
    // ...
};

stream у них есть способность escrbir любая информация о фундаментальном типе и тип std::string посредством оператора вставки, но если тип T он не типов, которые оператор принимает, тогда ты не сможешь делать инъекцию этому в файл если только ты не веришь в перегрузку оператора (бойтесь, что он дал бы для другого вопроса), или определи различную рутину serialización (боится, что он дал бы для другого вопроса).


1Cuatrocientos двадцать девять тысяч четыреста девяносто шесть биллионов семьсот двадцать девять тысячи пятьсот шестнадцать миллион четыреста тридцать одни тысячи восемьсот тридцать четыре.

1
ответ дан 24.11.2019, 12:58

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

И уже чтобы читать значит переделывать узлы, когда ты увидишь delimitador, ты создаешь информацию. и ты повторяешь до следующего delimitador.

0
ответ дан 24.11.2019, 12:58

Ты нуждался бы в двух функциях, одной, чтобы переворачиваться, и другая, чтобы писать. Ты можешь повторно использовать функцию imprimir чтобы писать, но вместо того, чтобы без получать параметры, перемещая разгрузку, где ты хочешь сохранять данные:

void Cola<T>::imprimir(std::ostream& os)
{
  Nodo* recorrido = inicio;

  // cout << "Listado de todos los elementos de la cola." << endl;
  // La interacción con el usuario nunca dentro de las clases, siempre
  // fuera. En nuestro caso particular, para que las funciones de
  // lectura y escritura (esta función) sean equivalentes.

  while (recorrido != NULL) {
     os << "|" << recorrido->dato << "|"
          << "-";
     recorrido = recorrido->siguiente;
 }

 os << endl;
}

Обрати внимание, что я заменил std::cout из-за os. Это такое потому что std::cout это объект типа std::ostream. Ты можешь использовать функцию таким образом:

Cola<T> c;
// ...
c.imprimir(std::cout); // Imprimir en la salida estándar

Но также:

std::ofstream file("file_path");
Cola<T> c;
// ...
c.imprimir(file);

Почему? Потому что std::ofstream это класс, который он получает в наследство std::ostream. В других словах, объекте типа std::ofstream, он также типа std::ostream.

std::ostream это вид характерного интерфейса для разгрузок вывода (объекты, в которых ты можешь вводить данные), и есть два класса, которые происходят std::ostream: std::ofstream (файлы) и std::ostringstream (относиться к цепи как к разгрузке). Твоя функция imprimir(std::ostream&) функционируй для любого типа разгрузки вывода.

Для чтения:

void Cola<T>::leer(std::istream& is)
{
    T sig_elto;
    char saltar_char;

    while (is) {
        // Ignorar primer |, luego sacamos el elemento en sí,
        // y luego ignoramos el segundo | y el -
        is >> saltar_char >> sig_elto >> saltar_char >> saltar_char;
        insertar(sig_elto);
    }

}

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

Cola<std::string> c1, c2;
c1.leer(std::cin);

std::ifstream file("cola_guardada.txt");
c2.leer(file);

Вероятно будь должен налаживать функцию leer из-за того, что избегает возможные разрывы линии, например.

Ты сможешь представлять себе то, что std::ifstream также он типа std::istream (, и что std::cin это глобальный объект типа std::istream). Из-за аналогии, чтобы относиться к цепи как к разгрузке ввода, также мы имеем std::istringstream.

Для файла, который они были бы обоими, чтением и написанием, мы имеем std::iostream и Ваши полученные в наследство версии std::fstream и std::stringstream.

0
ответ дан 24.11.2019, 12:58