Jump to content

Inserir texto sem escrever por cima


veaoum

Recommended Posts

Boa noite! Estou com um problema Imaginem que temos uma lista de nomes guardados num ficheiro chamado lista.txt e tenho que trocar um nome desse ficheiro por outro nome.

Caso as dimensões das strings sejam iguais não há problema mas caso sejam diferentes começam as duvidas:

1º caso o novo nome seja menor, deveria ar para usar o caracter DEL não?

2 Caso seja maior como é que posso fazer para escrever sem colocar apagar o que está lá escrito, ou seja, adicionar espaço ao ficheiro.

Aqui vai parte daquilo que eu fiz.

#include "stdafx.h" // Para apoio na compilação obrigatório no visual studio
#include <iostream> // uso cout a cin
#include <iomanip> // formatação de dados input output
#include <stdio.h> // para printf e scanf
#include <string> // manipular variavel string
#include <conio.h>
#include <fstream>
using namespace std; // Para facelitar o uso do cin e cout
int main()
{
FILE *fp1, *fp2;
std::locale::global(std::locale(""));
string nomenoficheiro, nomeaprocurar, nomenovo;
fstream fp; //criar este ficheiro c os nomes abaixo...
long posicao;

char back_space = 8;
int i = 0;
bool encontrado = false;
cout << "Nome a procurar? ";
getline(cin, nomeaprocurar);
cout << "Novo nome? ";
getline(cin, nomenovo);
fp.open("lista.txt", ios::in | ios::out);
fp1 = fopen("lista.txt", "r+");
if (fp.is_open()) {
 cout << "Está aberto.\n\n";
}
fseek(fp1, 0, SEEK_SET);
while (getline(fp, nomenoficheiro) && !encontrado) {
 if (nomeaprocurar == nomenoficheiro) {
  if (nomenovo.size() == nomeaprocurar.size()) {
fprintf(fp1, nomenovo.c_str());
  }
  else if (nomenovo.size() < nomeaprocurar.size()) {
fprintf(fp1, nomenovo.c_str());
for (i == 0; i < nomeaprocurar.size() - nomenovo.size(); i++) {
 fputc(127,fp1); // tecla del
}
  }
  //fprintf(fp1, nomenovo.c_str());
  encontrado = true;
  fclose(fp1);
  fp.close();
 }

 fseek(fp1, fp.tellg(), SEEK_SET);
}
if (encontrado) {
 cout << "Substituido";
}
else {
 cout << "NAO EXISTE";
}
//fp.close();
cout << endl;
_getch();
}
Link to comment
Share on other sites

nem vou olhar para o código, isto porque a maneira como apresentas o problema demonstra aquilo que não sabes.

não podes simplesmente fazer esse tipo de alteração, ponto. não existe paninhos quentes neste tipo de situação.

se pretendes alterar um ficheiro de texto, a maneira mais simples é :

- criar um segundo ficheiro

- passar toda a info até a linha/info que pretendes alterar para o novo ficheiro

- copiar a linha/info alterada

- copiar o resto da info

- apagar o ficheiro original

- renomear o segundo ficheiro para o nome do ficheiro original

sim, parece algo muito complexo para algo que inicialmente dá a sensação de que é simples, mas não é.

quando estudares sobre sistemas operativos e sistemas de ficheiros irás perceber o problema na sua totalidade.

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Isso não é verdade, essa é a alternativa fácil e está feito dessa forma, apenas tentei alterar porque não gosto disso da forma que tu falas vais percorrer o ficheiro todo uma vez garantidamente. O meu objectivo era no pior dos casos percorrer o ficheiro uma vez. Tentar optimizar o código.

Não haverá mesmo nenhuma forma de adicionar sem fazer "estragos" no ficheiro? Já tentei com o fstream e com o fopen.

P.S.: Aquilo que tenho feito é um bocado diferente daquilo que sugeres e menos optimizado. Faz isto:

- criar um segundo ficheiro

- passar toda a info até a linha/info que pretendes alterar para o novo ficheiro

- copiar a linha/info alterada

- copiar o resto da info

- copiar toda a info do segundo ficheiro para o original

- apagar o segundo ficheiro

Ou seja leio duas vezes o ficheiro.

Link to comment
Share on other sites

Isso não é verdade, essa é a alternativa fácil e está feito dessa forma

ok, foi ver o código. e sabes o que vi ? nada do que disse.

vi uma carrada de fssek's e printf's. por outras palavras : andas a alterar o ficheiro original.

mas prontos, se preferes ter a tua razão e ignorar o meu post, está completamente à vontade.

fica somente a referência ao frase fulcral da minha resposta inicial:

não podes simplesmente fazer esse tipo de alteração, ponto.

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Não estou a defender uma razão que possa ter ou não, até porque a minha questão era se existe alguma forma de o fazer porque não sei se é possível. Estou apenas a tentar solucionar de outra forma, mais nada. E pedi ajuda o código que tens ai é para o meu objectivo de momento logo coloco aqui a parte a funcionar.

Apenas achei interessante e mais eficiente se fosse possível fazer desta forma.

Link to comment
Share on other sites

Aqui está o código:

#include "stdafx.h" // Para apoio na compilação obrigatório no visual studio
#include <iostream> // uso cout a cin
#include <iomanip> // formatação de dados input output
#include <stdio.h> // para printf e scanf
#include <string> // manipular variavel string
#include <conio.h>
#include <fstream>
using namespace std; // Para facelitar o uso do cin e cout
int main()
{
std::locale::global(std::locale(""));
string nomenoficheiro, nomeaprocurar, nomenovo;
ifstream fp; //criar este ficheiro c os nomes abaixo...
ofstream fp1;
bool encontrado = false;

cout << "Nome a procurar? ";
getline(cin, nomeaprocurar);

cout << "Novo nome? ";
getline(cin, nomenovo);

fp.open("lista.txt");
fp1.open("flista.txt");

while (getline(fp, nomenoficheiro)) {
 if (nomeaprocurar == nomenoficheiro) {
  fp1 << nomenovo<<"\n";
  encontrado = true;
 }
 else {
  fp1 << nomenoficheiro << "\n";
 }
}
fp.close();
fp1.close();
if (encontrado) {
 fp.open("flista.txt");
 fp1.open("lista.txt");
 while (getline(fp, nomenoficheiro)) {
   fp1 << nomenoficheiro << "\n";
 }
 fp.close();
 fp1.close();
 cout << "Substituido\n";
}
else {
 cout << "NAO EXISTE\n";
}
_getch();
}
Link to comment
Share on other sites

A diferença entre o teu e o algoritmo que te deu o hippo é a parte final. Ele diz para apagares o ficheiro original e renomeares o novo, ao passo que tu copias o novo para o antigo linha por linha.

De resto, é a mesma coisa e é o que tem de ser feito. Tens uma alternativa que é ler até ao sítio certo, ler o resto do ficheiro para um buffer, truncares o ficheiro no sítio que queres, colocar o novo nome, e escrever o buffer no fim do ficheiro.

Continuas a ter de ler o ficheiro inteiro uma vez, e vais aumentar a complexidade do algoritmo de forma completamente desnecessária.

Link to comment
Share on other sites

A diferença entre o teu e o algoritmo que te deu o hippo é a parte final. Ele diz para apagares o ficheiro original e renomeares o novo, ao passo que tu copias o novo para o antigo linha por linha.

Sim eu até disse isso. O algoritmo do hippo é mais eficiente do que o meu e vou fazer essa correcção.

É pena porque se falarmos de um ficheiro gigante e tivermos que fazer uma alteração deste género vai demorar muito tempo.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.