veaoum Posted December 1, 2015 at 01:04 AM Report Share #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(); } Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 1, 2015 at 01:26 AM Report Share #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 Link to comment Share on other sites More sharing options...
veaoum Posted December 1, 2015 at 09:15 AM Author Report Share #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. Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted December 1, 2015 at 09:33 AM Report Share #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 Link to comment Share on other sites More sharing options...
veaoum Posted December 1, 2015 at 10:06 AM Author Report Share #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. Link to comment Share on other sites More sharing options...
veaoum Posted December 1, 2015 at 10:18 AM Author Report Share #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(); } Link to comment Share on other sites More sharing options...
Flinger Posted December 2, 2015 at 10:54 AM Report Share #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. Link to comment Share on other sites More sharing options...
veaoum Posted December 2, 2015 at 11:58 AM Author Report Share #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. Link to comment Share on other sites More sharing options...
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