0

Programa que genera un menú cuyas opciones son:

  1. Abrir una cuenta (nombre_cliente, saldo, apertura, numero de cuenta).
  2. Depositar solicitando el numero de cuenta si existe.
  3. Cerrar el programa y grabar en un archivo las cuentas abiertas.
Requerimientos

Se deben utilizar funciones: para el menú apertura y deposito. Sólo utilizar un vector para almacenar los tres datos de apertura (nombre, saldo, numero de cuenta). Utilizar un vector struct.

No se qué hacer para hacer una función que me modifique un dato de un archivo en C++

Este es mi código:

#include<iostream>
#include<stdlib.h>
#include<fstream>
#include<conio.h>

using namespace std;

void menu();
void abrirCuenta();
void depositar();

struct clientes{
    string nombre;
    float saldo;
    int numeroC;
}cliente[100];

int c=0;

ofstream archivo;
ifstream archiv;

int main(){
    menu();
}

void menu(){
        int op;
    do{
        cout<<"1. Abrir cuenta"<<endl;
        cout<<"2. Depositar"<<endl;
        cout<<"3. cerrar"<<endl;

        cin>>op;

        switch(op){
            case 1:
                abrirCuenta();
            break;
            case 2:
                depositar();
            break;
            case 3:
                
            break;
        }
        if (op!=1 && op!=2 && op!=3){   
            cout<<"opcion incorrecta"<<endl;
        }
    }while(op!=1 && op!=2 && op!=3);
}

void abrirCuenta(){
    fflush(stdin);
    cout<<"Ingrese su nombre: "; getline(cin, cliente[c].nombre);
    cout<<"Ingrese su monto inicial: "; cin>>cliente[c].saldo;
    cliente[c].numeroC=c+1;
    cout<<"Su numero de cuenta es: "<<cliente[c].numeroC;
    

    archivo.open("Clientes.txt", ios::out);//abriendo archivo
        if(archivo.fail()){
            cout<<"No se pudo abrir el archivo"<<endl;
            exit(1);
        }
        archivo<<cliente[c].numeroC<<"\t"<<cliente[c].nombre<<"\t"<<cliente[c].saldo<<"\t";
    archivo.close();//cerrando archivo
}

void depositar(){
    bool encontrado=false;
    int nCuenta=0, clave;
    string Nombre;
    float saldo;

    archivo.open("auxiliar.txt", ios::out);//abrir en forma de escritura
    archiv.open("clientes.txt", ios::in);//abrir en forma de escritura
    if(archivo.is_open() && archiv.is_open()){
        cout<<"ingrese su numero de cuenta: "; cin>>nCuenta;
        archiv>>clave;
        while(!archiv.eof()){
            archiv>>Nombre>>saldo;

            if(nCuenta==clave){
                encontrado=true;
                cout<<"numero de cuenta: "<<clave<<endl;
                cout<<"Nombre del cliente: "<<clave<<endl;
                cout<<"saldo actual: "<<clave<<endl;
                cout<<"\v";
                cout<<"Ingrese su el monto a depositar: "; cin>>saldo;

                archivo<<clave<<" "<<Nombre<<" "<<saldo<<endl;

                cout<<"Deposito realizado"<<endl;
            }


        }
    }else{
        cout<<"no se pudo abrir el archivo";
    }
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
pipe
  • 23
  • 3
  • 3
    Y cuál es el problema con ese código? Sale algún error? Estalla tu PC en lllamas? Ve a [edit] y explica cuál es el problema y los errores que encuentras. "No me funciona" no significa absolutamente nada – Alfabravo May 16 '22 at 23:35
  • `while(!archiv.eof()){ archiv>>Nombre>>saldo; ...` => `while(archiv>>Nombre>>saldo) { ...` – Ted Lyngmo May 16 '22 at 23:40

1 Answers1

0

No se qué hacer para hacer una función que me modifique un dato de un archivo en C++

No lo sabes tú ni lo sabe nadie... porque no se pueden modificar datos en archivos de C++ a no ser que los datos sean de tamaño homogéneo, que no es tu caso.

Lo que debes hacer en este caso es reescribir el archivo al completo por cada dato modificado (o en el mejor de los casos, reescribir desde el dato modificado hasta el final del archivo).

Para esa tarea yo te aconsejo hacer las siguientes modificaciones a tu código:

  1. Crear una sobrecarga del operador de inyección de datos a archivo para clientes:
    std::ofstream &operator <<(std::ofstream &o, const clientes &c) {
        return o << c.numeroC << '\t' << c.nombre << '\t' << c.saldo << '\t';
    }
    
  2. Por cada modificación de datos, reescribir el archivo al completo, yo te aconsejo una función de guardado:
    void guardar_datos(const auto &datos_clientes) {
        if (std::ofstream datos{"clientes.txt"}) {
            for (const auto &cliente : datos_clientes) {
                datos << cliente;
            }
        }
    }
    

Si te fijas, he hecho notables cambios a tu código, te voy a listar esos cambios y otros consejos:

  1. NO uses variables globales.
  2. La función main debe devolver un valor.
  3. Si un tipo guarda UN dato, su nombre debe ser en singular, no plural:
    struct cliente{ // La 'struct' guarda UN dato, su nombre debe ser singular.
        string nombre;
        float saldo;
        int numeroC;
    }clientes[100]; // La formación guarda VARIOS datos, su nombre debe ser plural.
    
  4. Los flujos de archivo std::ofstream son de salida (output file stream) no necesitas especificar que son de salida al abrirlos.
  5. Los flujos de archivo std::ifstream son de entrada (input file stream) no necesitas especificar que son de salida al abrirlos.
  6. Los flujos de datos son convertibles a booleano, su valor es falso cuando ha habido un fallo al abrir, leer o escribir en el flujo.
  7. Los flujos de datos se cierran automáticamente al finalizar su ciclo de vida, no es necesario cerrarlos explícitamente.
  8. La cabecera <stdlib.h> es de y no debe ser usada en , si realmente necesitas usarla usa su versión adaptada a : <cstdlib>.
  9. La cabecera <conio.h> es de y no debe ser usada en , no existe versión adaptada a porque no es una cabecera estándar.
  10. Si tienes varias llamadas seguidas a std::cout puedes transformarlo a una sola llamada.
  11. Usa contenedores estándar para guardar datos, evita usar formaciones porque son mucho menos flexibles.
  12. Inicializa tus variables, tanto las sueltas como las que pertenecen a un objeto, las del objeto intenta inicializarlas en el punto de definición o en el constructor:
    struct cliente {
     string nombre;
     float saldo = .0f;
     int numeroC = 0;
    };
    
  13. No abuses de std::endl.

Si aplicas todos los puntos anteriores, tu código podría parecerse a:

#include <iostream>
#include <fstream>
#include <list>
#include <algorithm>

using namespace std;

struct cliente {
    string nombre;
    float saldo = .0f;
    int numeroC = 0;
};

ofstream &operator <<(ofstream &o, const cliente &c) {
    o << c.numeroC << '\t' << c.nombre << '\t' << c.saldo << '\t';
    return o;
}

void menu();
void abrirCuenta(list<cliente> &);
void depositar(list<cliente> &);

int main() {
    menu();
    return 0;
}

void menu() {

    list<cliente> clientes;
    int op;

    do {
            cout <<
            "1. Abrir cuenta\n"
            "2. Depositar\n"
            "3. cerrar\n";

            cin >> op;

        switch (op) {
        case 1:
            abrirCuenta(clientes);
            break;
        case 2:
            depositar(clientes);
            break;
        case 3:
            break;
        }

        if (op!=1 && op!=2 && op!=3){   
            cout << "opcion incorrecta\n";
        }
    } while (op != 1 && op != 2 && op != 3);
}

void guardar_datos(list<cliente> &datos_clientes) {
    if (ofstream datos{"clientes.txt"}) {
        for (const auto &cliente : datos_clientes) {
            datos << cliente;
        }
    }
    else {
        cout << "No se pudo abrir el archivo\n";
    }
}

void abrirCuenta(list<cliente> &clientes) {
    static int numero_cliente = 0;
    cliente c;

    cout << "Ingrese su nombre: ";
    getline(cin, c.nombre);

    cout << "Ingrese su monto inicial: ";
    cin >> c.saldo;

    c.numeroC = numero_cliente++;
    cout << "Su numero de cuenta es: " << c.numeroC;

    clientes.push_back(c);

    guardar_datos(clientes);
}

void depositar(list<cliente> &clientes) {
    int nCuenta = 0;
        cout << "ingrese su numero de cuenta: ";
    cin >> nCuenta;

    auto found = std::find_if(clientes.begin(), clientes.end(), [&nCuenta](const cliente &c)
    {
        return c.numeroC == nCuenta;
    });

    if (found != clientes.end()) {
        cout
            << "numero de cuenta: " << found->numeroC << '\n'
            << "Nombre del cliente: " << found->nombre << '\n'
            << "Saldo actual: " << found->saldo << '\n'
            << "Ingrese su el monto a depositar: ";

        float saldo;
        cin >> saldo;

        found->saldo += saldo;

        cout << "Deposito realizado\n";

        guardar_datos(clientes);
    }
    else {
        cout << "Cliente " << nCuenta << " no encontrado\n";
    }
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82