Soy bastante nuevo en C++ y estoy tratando de averiguar cómo escribir un registro en el formato de esta estructura a un archivo de texto:

struct user {
    int id;
    char username [20];
    char password [20];
    char name [20];
    char email [30];
    int telephone;
    char address [70];
    int level;
}; 

Hasta ahora, soy capaz de escribir bien, pero sin incrementado un número de identificación, como no sé cómo calcular el número de registros, por lo que el archivo se ve algo como esto después de lo que he escrito los datos en el archivo.

1 Nick pass Nick email tele address 1
1 user pass name email tele address 1
1 test test test test test test 1
1 user pass Nick email tele addy 1
1 nbao pass Nick email tele 207 1

Usando el siguiente código:

ofstream outFile;

outFile.open("users.dat", ios::app);

//User input of data here

outFile << "\n" << 1 << " " << username << " " << password << " " << name << " "
        << email << " " << telephone << " " << address  << " " << 1;
cout << "\nUser added successfully\n\n";

outFile.close();

Así, ¿cómo puedo incrementar el valor para cada registro en la inserción y cómo orientar un registro específico en el archivo?

EDIT: he llegado a ser capaz de mostrar cada línea:

  if (inFile.is_open())
    {
    while(!inFile.eof())
    {

    cout<<endl;
    getline(inFile,line);
    cout<<line<<endl;

    }
    inFile.close();
    }
  • no es necesario que el archivo a ser texto sin formato? Será su formato de permitir la eliminación de los objetos?
  • uso std::string en lugar de C-estilo char* cadenas y omitir la <<" " cuando la lectura (es automáticamente coma espacio en blanco).
  • el uso de C-estilo char * también automáticamente se come el espacio en blanco. Además, << es para escribir, no de la lectura.
  • Después de que me puede seleccionar un registro voy a implementar la posibilidad de editar y eliminar un registro.
  • Las cosas se empiezan a romper si el nombre de usuario/contraseña/nombre/correo electrónico/dirección de contener un carácter de espacio.
InformationsquelleAutor nbaosullivan | 2012-05-04

6 Comentarios

  1. 1

    Lo que hasta el momento no es malo, excepto que no puede manejar los casos donde no hay espacio en las cadenas (por ejemplo, en la dirección!)

    Lo que usted está tratando de hacer es escribir una muy básica de la base de datos. Requiere de tres operaciones que deben ser aplicadas por separado (aunque subtramas que se les puede dar un mejor rendimiento en ciertos casos, pero estoy seguro de que no es su preocupación aquí).

    • Insertar: Que ya lo tienen implementado. Única cosa que puede cambiar es el " " a "\n". De esta manera, cada campo de la estructura está en una nueva línea y su problema con los espacios que se resuelvan. Más tarde, cuando de la lectura, usted necesita leer línea por línea
    • De búsqueda: la búsqueda, basta con abrir el archivo, leer struct por struct (que en sí consiste en la lectura de muchas de las líneas correspondientes a su estructura de campos) y la identificación de las entidades de su interés. Qué hacer con ellos es otro tema, pero el caso más simple sería para devolver la lista de entidades de contrapartida en una matriz (o vector).
    • Eliminar: Esta es similar a la búsqueda, a menos que usted tenga que volver a escribir el archivo. Lo que se hace es, básicamente, de nuevo leer struct por struct, ver cuáles se ajustan a tus criterios de eliminación. Ignorar aquellas que coinciden, y escribir (como la parte de inserción) el resto a otro archivo. Después de esto, usted puede reemplazar el archivo original con el nuevo archivo.

    Aquí es un pseudo-código:

    Write-entity(user &u, ofstream &fout)
        fout << u.id << endl
             << u.username << endl
             << u.password << endl
             << ...
    
    Read-entity(user &u, ifstream &fin)
         char ignore_new_line
         fin >> u.id >> ignore_new_line
         fin.getline(u.username, 20);
         fin.getline(u.password, 20);
         ...
         if end of file
             return fail
    
    Insert(user &u)
         ofstream fout("db.dat");
         Write-entity(u, fout);
         fout.close();
    
    Search(char *username) /* for example */
         ifstream fin("db.dat");
         user u;
         vector<user> results;
         while (Read-entity(u))
             if (strcmp(username, u.username) == 0)
                 results.push_back(u);
         fin.close();
         return results;
    
    Delete(int level) /* for example */
         ifstream fin("db.dat");
         ofstream fout("db_temp.dat");
         user u;
         while (Read-entity(u))
             if (level != u.level)
                 Write-entity(u, fout);
         fin.close();
         fout.close();
         copy "db_temp.dat" to "db.dat"

    Lado nota: Es una buena idea colocar el \n después de que los datos han sido escritos (de modo que el archivo de texto sería final en una nueva línea)

    • Wow, muchas gracias, has superado mucho para mí!
    • +1 Porque de introducir el concepto de un User clase. PERO que pasa por alto demasiados problemas. También se rompe si cualquier cadena es menor que su máximo (que va a ser casi siempre). Probablemente se romperá si usted tiene demasiados espacios y no cubre el manejo de errores bastante bien.
    • Me restó importancia a los problemas de forma intencionada. Primero de todo, no voy a escribir todo el programa aquí, sólo la idea básica. Segundo, el OP es realmente nuevo en C++, creo que estorban el algoritmo con un montón de comprobación de error sería sólo se confunda. Finalmente, esta forma de escritura de una base de datos chupa todos modos y es sólo bueno para una simple práctica del programa.
  2. 1

    El uso de métodos típicos de al menos usted tendrá que usar fijar el tamaño de los registros, si quieres tener acceso aleatorio a la hora de leer el archivo, así que decir tiene 5 caracteres para el nombre se guardará como

    bob
    bob\0\0
    bob\0\0

    o cualquier otra cosa que se utiliza para rellenar, de esta forma puedes índice con el número de registro * registro de tamaño.

    Para incrementar el índice de la manera que usted está haciendo, usted tendrá que leer el archivo para encontrar el alto índice existente y lo incrementa. O usted puede cargar el archivo en la memoria y anexar el registro nuevo y escribir el archivo

    std::vector<user> users=read_dat("file.dat");
    user user_=get_from_input();
    users.push_back(user_);
    
    then write the file back
    std::ofstream file("file.dat");
    for(size_t i=0; i!=users.size(); ++i) {
        file << users.at(i); 
       //you will need to implement the stream extractor to do this easily
    }
  3. 1

    Me sugieren para envolver el manejador de archivos en una Clase y, a continuación, se sobrecarga el operador de >> and << para su estructura, con esto se va de control de entrada y salida.
    Por ejemplo

    struct User{
    ...
    };
    
    typedef std::vector<User> UserConT;
    
    struct MyDataFile
    {
      ofstream outFile;
      UserConT User_container;
    
      MyDataFile(std::string const&); //
      MyDataFile& operator<< (User const& user); //Implement and/or process the record before to write
      MyDataFile& operator>> (UserConT & user); //Implement the extraction/parse and insert into container
      MyDataFile& operator<< (UserConT const & user); //Implement extraction/parse and insert into ofstream 
    };
    
    MyDataFile& MyDataFile::operator<< (User const& user)
    {
      static unsigned myIdRecord=User_container.size();
      myIdRecord++;
      outFile << user.id+myIdRecord << ....;
      return *this;
    }
    
    
    
    int main()
    {
       MydataFile file("data.dat");
    
       UserConT myUser;
       User a;
       //... you could manage a single record  
       a.name="pepe"; 
       ...
       file<<a;
       ..//
    
    }
    • +1 para la creación de la User tipo. Pero no es necesario para la MyDataFile (de hecho yo consideraría malo como usted no puede ahora leer un User de un std::stringstream (o de otro stream)). Usted puede escribir una función libre para leer un usuario a partir de una secuencia: std::istream& operator>>(std::istream& stream, User& data) { /* stuff */} y std::ostream& operator<<(std::ostream& stream, User const& data) { /*Stuff*/}
  4. 0

    Una .Archivo Dat es normalmente un simple archivo de texto en sí, que puede ser abierto con el bloc de notas . Así , usted puede simplemente leer la Última Línea del archivo , leer , extraer el primer carácter , convertirlo en entero . A continuación, incrementar el valor y listo .
    El código de ejemplo aquí :

      #include <iostream.h>
      #include <fstream.h>
      using namespace std;
    
      int main(int argc, char *argv[])
      {
        ifstream in("test.txt");
    
      if(!in) {
           cout << "Cannot open input file.\n";
           return 1;
        }
    
         char str[255];
    
         while(in) {
           in.getline(str, 255);  //delim defaults to '\n'
            //if(in) cout << str << endl;
         }
        //Now str contains the last line , 
        if  ((str[0] >=48) || ( str[0] <=57))
        {
          int i = atoi(str[0]);
          i++;
        } 
        //i contains the latest value , do your operation now
        in.close();
    
         return 0;
         }
  5. 0

    Suponiendo que el formato de archivo no deben ser legibles para el ser humano.

    Puede escribir la estructura a archivo como.

    outFile.open("users.dat", ios::app | ios::binary);
    user someValue = {};
    outFile.write( (char*)&someValue, sizeof(user) );
    
    int nIndex = 0;
    user fetchValue = {};
    ifstream inputFile.open("user.data", ios::binary);
    
    inputFile.seekg (0, ios::end);
    
    int itemCount = inputFile.tellg() / sizeof(user);
    
    inputFile.seekg (0, ios::beg);
    
    if( nIndex > -1 && nIndex < itemCount){
        inputFile.seekg ( sizeof(user) * nIndex , ios::beg);
        inputFile.read( (char*)&fetchValue, sizeof(user) );
    }
    • Yo no veo ninguna punteros en la estructura de la op. Tal vez estoy en busca de algo?
    • Opps. Lo siento 🙂
  6. 0

    El código que se escribe en el archivo es una función miembro de usuario struct?
    De lo contrario, no veo la conexión entre la salida y la estructura.

    Posibles cosas que hacer:

    • escribir el id de miembro en lugar de 1
    • el uso de un contador para la identificación y el incremento en cada escritura
    • no escriba el id y cuando la lectura de utilizar el número de línea como de identificación de

Dejar respuesta

Please enter your comment!
Please enter your name here