veaoum Posted December 1, 2015 at 01:04 AM Report #590253 Posted December 1, 2015 at 01:04 AM 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(); }
HappyHippyHippo Posted December 1, 2015 at 01:26 AM Report #590254 Posted December 1, 2015 at 01:26 AM 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 Portugol Plus
veaoum Posted December 1, 2015 at 09:15 AM Author Report #590261 Posted December 1, 2015 at 09:15 AM 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.
HappyHippyHippo Posted December 1, 2015 at 09:33 AM Report #590262 Posted December 1, 2015 at 09:33 AM 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 Portugol Plus
veaoum Posted December 1, 2015 at 10:06 AM Author Report #590263 Posted December 1, 2015 at 10:06 AM 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.
veaoum Posted December 1, 2015 at 10:18 AM Author Report #590264 Posted December 1, 2015 at 10:18 AM 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(); }
Flinger Posted December 2, 2015 at 10:54 AM Report #590294 Posted December 2, 2015 at 10:54 AM 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.
veaoum Posted December 2, 2015 at 11:58 AM Author Report #590297 Posted December 2, 2015 at 11:58 AM 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now