Boa noite. Eu tenho visto muitas pessoas com dúvidas do género que vou tentar explicar neste tópico. Com a contribuição de outros participantes do forum vou mantendo este post actualizado.
1º Apresentação de um problema geral no qual vocês têm tido dificuldades:
Leitura de um ficheiro para poder construir um array com informação que é para ser editada pelo utilizador. Depois de terem sido feitas as modificações guardar essas alterações no ficheiro.
Vou separar este problema em 4 fases:
1º - Leitura do ficheiro para construir o objecto
2º - Inserção de um elemento no array
3º - Procurar um elemento no array para o modificar
4º - Escrever modificações no ficheiro
Antes de continuar vou descrever um pouco as estruturas de dados mais abordadas neste forum. Se forem iniciantes ou não estiverem muito preocupados com a eficiência podem saltar para o 1º passo.
Um array é a estrutura de dados mais simples. Pode ser indexada para obter e modificar os seus valores. A inserção deverá ser sequencial senão torna-se lenta.
Um arraylist é um array só que quando fica cheio é feita uma expansão para dar a possibilidade de inserir novos elementos.
Escolha de uma estrutura de dados:
Como estamos a lêr de um ficheiro não sabemos quantos elementos vai ter o nosso array por isso deveriamos escolher um arraylist.
Mas na verdade a estrutura de dados mais eficiente, para inserção remoção e pesquisa é uma hashtable.
Se for preciso ordenar então serão outras que não vou aqui falar (por enquanto)
1º Leitura de um ficheiro
A primeira coisa a saber é como é que a informação está organizada no ficheiro.
Por exemplo:
Se a cada linha corresponder um objecto do nosso array então sabemos que temos que contruir um objecto para cada linha do ficheiro
Se os campos estiverem separados por ';' então sabemos que teremos tantos campos como os ';' que aparecerem na linha (mais um)
Agora só temos que saber qual é o tipo de dados de cada campo para meter numa variável do tipo correspondente.
Vou agora apresentar um código genérico para a criação de uma Stream (para lêr de um ficheiro) lendo linha a linha:
Neste momento temos cada um dos campos no array de String campos e agora gostávamos de agrupar esses campos para depois inserirmos no arraylist.
Vi muitos utilizadores com este problema a sugerirem colocar a informação num array bidimensional, do que eu discordo completamente.
Uma das maneiras mais práticas e simples é criar uma class com cada um dos campos. Vou supor que o nosso ficheiro tem 3 campos por cada elemento. <nome>;<marca>;<preço>
Então criaria a seguinte class:
2º Inserção de elementos no array
E agora temos uma abstracção daquilo que é cada elemento do nosso Array, sabemos que é um produto com aquelas propriedades que podemos alterar.
Vou então simular a criação de um objecto para inserir no arraylist continuando no while.
Quando o nosso ciclo terminar teremos o array com todos os Produtos que o ficheiro possuía. Agora o nosso problema é procurar elementos para que o utilizador o possa editar
3º Procurar um elemento
Este problema depende essencialmente de duas questões.
A primeira é saber se podem haver elementos repetidos na vossa estrutura de dados.
A segunda é saber por que atributo é que estão a procurar o vosso elemento.
No caso genérico assume-se que há elementos repetidos por isso é o que vou fazer. Vou procurar os meus elementos por Marca.
Como estamos a usar um arraylist que não foi feito por nós temos que perceber qual é maneira de encontrar um elemento numa estrutura de dados.
A maneira convencional de encontrar um elemento na estrutura de dados é percorrer os elementos e comparar um a um (com o método equals) e retornar o 1º elemento.
Então temos que implementar o nosso método equals em em Produto.
NOTA: O método equals serve para comparar dois elementos se por acaso quiséssemos comparar dois elementos pelos campos todos então teríamos que ter os campos todos no nosso método equals e a nossa procura por um dos campos de Produto já não funcionaria. Portanto esta solução fica assim para explicar apenas uma maneira simples de fazer o desejado.
Agora podemos procurar um elemento com o método IndexOf
Então mas isto levanta outro problema como é que procuraríamos o próximo elemento da mesma marca?
existe para isso outro IndexOf que procura um elemento a partir de determinado índice
E assim fica resolvida a parte de procurar um elemento e alterar os seus valores.
4º Escrever no ficheiro as modificações
O único problema aqui é termos que escrever o objecto no mesmo formato que o lemos no ficheiro. Então eu sugiro que façam o método ToString na vossa classe e depois basta percorrer o array e escrever cada elemento.
1º Apresentação de um problema geral no qual vocês têm tido dificuldades:
Leitura de um ficheiro para poder construir um array com informação que é para ser editada pelo utilizador. Depois de terem sido feitas as modificações guardar essas alterações no ficheiro.
Vou separar este problema em 4 fases:
1º - Leitura do ficheiro para construir o objecto
2º - Inserção de um elemento no array
3º - Procurar um elemento no array para o modificar
4º - Escrever modificações no ficheiro
Antes de continuar vou descrever um pouco as estruturas de dados mais abordadas neste forum. Se forem iniciantes ou não estiverem muito preocupados com a eficiência podem saltar para o 1º passo.
Um array é a estrutura de dados mais simples. Pode ser indexada para obter e modificar os seus valores. A inserção deverá ser sequencial senão torna-se lenta.
Um arraylist é um array só que quando fica cheio é feita uma expansão para dar a possibilidade de inserir novos elementos.
Escolha de uma estrutura de dados:
Como estamos a lêr de um ficheiro não sabemos quantos elementos vai ter o nosso array por isso deveriamos escolher um arraylist.
Mas na verdade a estrutura de dados mais eficiente, para inserção remoção e pesquisa é uma hashtable.
Se for preciso ordenar então serão outras que não vou aqui falar (por enquanto)
1º Leitura de um ficheiro
A primeira coisa a saber é como é que a informação está organizada no ficheiro.
Por exemplo:
Se a cada linha corresponder um objecto do nosso array então sabemos que temos que contruir um objecto para cada linha do ficheiro
Se os campos estiverem separados por ';' então sabemos que teremos tantos campos como os ';' que aparecerem na linha (mais um)
Agora só temos que saber qual é o tipo de dados de cada campo para meter numa variável do tipo correspondente.
Vou agora apresentar um código genérico para a criação de uma Stream (para lêr de um ficheiro) lendo linha a linha:
Código:
StreamReader sr = new StreamReader(new FileStream("ficheiro.txt", FileMode.Open));
List<Produto> produtos = new List<Produto>();
string linha;
while ((linha=sr.ReadLine()) != null) {[INDENT]string[] campos = linha.Split(';'); //assumindo que os campos são separados por ;[/INDENT]
}
Neste momento temos cada um dos campos no array de String campos e agora gostávamos de agrupar esses campos para depois inserirmos no arraylist.
Vi muitos utilizadores com este problema a sugerirem colocar a informação num array bidimensional, do que eu discordo completamente.
Uma das maneiras mais práticas e simples é criar uma class com cada um dos campos. Vou supor que o nosso ficheiro tem 3 campos por cada elemento. <nome>;<marca>;<preço>
Então criaria a seguinte class:
Código:
public class Produto {[INDENT]string nome;[/INDENT]
string marca;
double preço; //podia ser um float também
public Produto(string nome, string marca, double preco) { //construtor com criação de um objecto completo
this.nome = nome;
this.marca = marca;
this.preco = preco;
}
}
2º Inserção de elementos no array
E agora temos uma abstracção daquilo que é cada elemento do nosso Array, sabemos que é um produto com aquelas propriedades que podemos alterar.
Vou então simular a criação de um objecto para inserir no arraylist continuando no while.
Código:
// Dentro do while...
string n = campos[0];string m = campos[1];
double p = Convert.ToDouble(linha[2]);
Produto c = new Produto(n, m, p);
produtos.Add(c);
Quando o nosso ciclo terminar teremos o array com todos os Produtos que o ficheiro possuía. Agora o nosso problema é procurar elementos para que o utilizador o possa editar
3º Procurar um elemento
Este problema depende essencialmente de duas questões.
A primeira é saber se podem haver elementos repetidos na vossa estrutura de dados.
A segunda é saber por que atributo é que estão a procurar o vosso elemento.
No caso genérico assume-se que há elementos repetidos por isso é o que vou fazer. Vou procurar os meus elementos por Marca.
Como estamos a usar um arraylist que não foi feito por nós temos que perceber qual é maneira de encontrar um elemento numa estrutura de dados.
A maneira convencional de encontrar um elemento na estrutura de dados é percorrer os elementos e comparar um a um (com o método equals) e retornar o 1º elemento.
Então temos que implementar o nosso método equals em em Produto.
Código:
//Na classe Produto
public override bool Equals(object obj)
{[INDENT]if (obj is Produto) { //verificar se o objecto que recebemos é um Produto[/INDENT]
[INDENT=2]Produto c = (Produto)obj;[/INDENT]
return c.marca.Equals(this.marca); //se for ver se a marca são iguais
}
return false;
}
NOTA: O método equals serve para comparar dois elementos se por acaso quiséssemos comparar dois elementos pelos campos todos então teríamos que ter os campos todos no nosso método equals e a nossa procura por um dos campos de Produto já não funcionaria. Portanto esta solução fica assim para explicar apenas uma maneira simples de fazer o desejado.
Agora podemos procurar um elemento com o método IndexOf
Código:
Produto procurar = new Produto(null, "Marca pretendida", 0); //mais um problema que temos é ter de criar um objecto produto para procurá-lo por Marca
int indice = produtos.IndexOf(procurar);
//Agora podemos fazer o que quisermos com o produto neste índice
if(indice >= 0) //o index of devolve um valor negativo (-1) caso não encontre elemento
produtos[indice].Preco = 100.14;
Então mas isto levanta outro problema como é que procuraríamos o próximo elemento da mesma marca?
existe para isso outro IndexOf que procura um elemento a partir de determinado índice
Código:
produtos.IndexOf(procurar, indice+1); //se fosse apenas indice devolvia o mesmo objecto
E assim fica resolvida a parte de procurar um elemento e alterar os seus valores.
4º Escrever no ficheiro as modificações
O único problema aqui é termos que escrever o objecto no mesmo formato que o lemos no ficheiro. Então eu sugiro que façam o método ToString na vossa classe e depois basta percorrer o array e escrever cada elemento.
Código:
//Na classe Produto
public override string ToString()
{[INDENT]StringBuilder builder = new StringBuilder(); //o string builder serve para juntar várias strings/valores[/INDENT]
builder.Append(nome); builder.Append(';');
builder.Append(marca); builder.Append(';');
builder.Append(preco);
return builder.ToString();
}
//escrever os elementos no ficheiro
StreamWriter sw = new StreamWriter(new FileStream("ficheiro.txt", FileMode.Open));
foreach(Produto produto in produtos)[INDENT]sw.WriteLine(produtoto.ToString());[/INDENT]
sw.Flush(); //não se esquecam de fazer flush para a infromação ser escrita no ficheiro
sw.Close();
sr.Close(); //não se esquecam de fechar as streams
Última edição: