Eu faço uma tentativa de entender a situação.
Missão : Despeja dois arquivos de texto em uma lista de discos .
➢ Criação de um TDA ou TAD (tipo de dados abstrato)
A primeira coisa é criar a estrutura Dis
(disco), desta forma.
struct Dis
{
string codigo;
string nombre;
string cantante;
string genero;
string discografia;
string precio;
Dis* siguiente; //Puntero al siguiente disco (importante).
};
struct Ind
{
int pos;
string codigo;
};
Nota: Esse tipo de estrutura não pode vir em um arquivo de texto, já que string
é um ponteiro para uma sequência de caracteres, que possuem tamanho dinâmico. Ou seja, todos os inteiros ocupam 32 ou 64 bits, dependendo da arquitetura, é sempre o mesmo número, mas uma string, "Pedro"
, não ocupa o mesmo que "Juan"
, a primeira 4 e a segunda 5, e apesar que, ambos são do tipo string, então você não pode fazer sizeof
.
➢ Gerenciar um arquivo
Para o gerenciamento de arquivos, você precisa da biblioteca padrão stdio
, o main
deve ser o seguinte. O stdlib
é por vezes necessário, por isso deixamos, sem prestar atenção ao que é usado.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv)
{
//Cosas por hacer.
return 0;
}
Para isso, é necessário saber como os arquivos são tratados em C , embora também funcione em C ++ , já que é uma linguagem cumulativa. Então, encontrei o seguinte link que lida com esse tópico:
Programação em C - Manipulação de arquivos - Wikibooks
.- Crie um ponteiro do tipo
FILE
. - Abra o arquivo usando a função fopen e atribua o resultado da chamada ao nosso ponteiro.
- Faça as várias operações ( leitura , escrita , etc.).
- Feche o arquivo usando a função fclose .
pseudo-código:
Abrir archivo.
Leerlo.
Volcarlo en lista_enlazada //Nodo.
Cerrarlo.
➢ Abra um arquivo
Uma lista de parâmetros opentype para a função fopen é:
"r"
: Lectura, el fichero debe existir.
"w"
: Escritura, se crea si no existe o se sobreescribe si existe.
"a"
: Escritura al final del contenido, si no existe se crea.
"r+"
: Lectura y escritura, el fichero debe existir.
"w+"
: Lectura y escritura, se crea si no existe o se sobreescribe si existe.
"r+b"
ó"rb+"
: Modo binario para actualización (lectura y escritura).
"rb"
: Modo binario para lectura.
No nosso caso vamos usar não binaria Reading , ou seja, "r"
, e estamos a tratar arquivos txt
(texto simples) e sem imagens ou áudio.
Código: estes são os passos 1 e 2 na mesma linha.
FILE* archivo = fopen("Datos.txt","r"); //Para Indice.txt es lo mismo.
➢ Leia um arquivo
1) Lee de a un caracter.
char fgetc(FILE *archivo)
2) Lee de a una línea o el tamaño indicado.
char *fgets(char *buffer, int tamano, FILE *archivo)
3) Lee de a bloques.
size_t fread(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);
4) Funciona igual que la entrada por teclado pero desde un archivo.
int fscanf(FILE *fichero, const char *formato, argumento, ...);
No nosso caso, estamos interessados em fgetc
, pois a estrutura Dis
não pode vir em um arquivo.
Código: Isso faz com que você leia um personagem.
while(feof(archivo) == 0)
{
char caracter = fgetc(archivo);
//Hacer algo con el caracter.
}
➢ Fechar um arquivo
Código:
fclose(archivo);
Já vimos as operações básicas sobre operações de arquivos. Agora temos que pensar em como despejá-lo na estrutura de dados Dis
.
Como não mostrou um exemplo arquivo de texto para saber como eles podem vir dados disco, eu vou assumir que tem o seguinte Formato Além disso, acho que desta forma você não precisa ler o arquivo de índice , então eu não vou tocar nesse tópico.
codigo_1 nombre_1 cantante_1 genero_1 discografia_1 precio_1
codigo_2 nombre_2 cantante_2 genero_2 discografia_2 precio_2
Etcétera...
Para que as duas exceções deve levar em conta qualquer caractere, exceto espaços (ou seja, ' '
, '\x20'
) ou uma quebra de linha ( '\n
, \r
, \x0D
\x0A
). Espaço significa o próximo campo da estrutura, a quebra de linha, o próximo disco.
➢ Como ler um arquivo com este novo formato?
Código: Retornamos o código anterior sobre a leitura do personagem e acrescentamos coisas a ele.
Dis discos = new Dis()
string texto="";
int i=0; //Número de campo actual.
string campos[6]; //Array de campos de texto que luego pasarán a los discos.
while(feof(archivo) == 0)
{
char caracter = fgetc(archivo);
if( caracter!=' ' && ! esSaltoLinea(caracter) )
{
texto = texto+((string)(caracter)); //Agrega un caracter al final del texto
}
else
{
campos[i] = texto;
texto = "";
if( caracter==' ' ){i++;} //Suma 1 a la variable i.
if( esSaltoLinea(caracter) )
{
//Volcar los textos de la variable campos al disco actual mediante un for.
//Cambiar al disco siguiente.
i=0; //Vuelve al campo inicial.
}
}
}
Observação: deixo algumas coisas desfeitas para que você possa praticar a calma, elas também não são tão difíceis.
➢ Ordenando uma estrutura
No exemplo a seguir, classificarei os discos por código. É necessário esclarecer que o método mais eficiente de ordenação é aquele que permite a busca binária, isto é efetivo apenas e é lento em comparação com o outro.
void ordenarPorCodigo( Dis discos )
{
Dis* principal = discos;
Dis* actual = principal;
Dis* auxiliar;
while( actual->siguiente!=NULL )
{
siguiente = actual->siguiente;
if( strcmp(actual->codigo,actual->siguiente->codigo) > 0 )
{
//Copiar los datos del actual en auxiliar.
//Copiar los datos del siguiente en actual.
//Copiar los datos del auxiliar en el siguiente.
//Ajustar los punteros del actual y del siguiente de manera correcta.
actual = principal;
}
actual = actual->siguiente;
}
}
Observação: Novamente, vou deixar esses pequenos detalhes como um desafio.