PDA

Visualizza la versione completa : [C++] Esercizio sui File di testo, non so come mettere mani


Skull260287
06-04-2008, 16:42
Sia dato un file testo “parole.txt” composto da sole lettere maiuscole. Ogni linea di testo è costituita da un carattere seguito da uno spazio e da una serie di parole tutte separate da uno spazio (compreso l’ultima).
Tutte le parole di un rigo dovrebbero iniziare o terminare con il carattere di inizio riga.
Scrivere una procedura che legga il file “parole.txt” e stampi a video tutte le parole che non verificano la condizione suddetta.
Esempio del file “parole.txt”
M MONDO MARE <eoln>
O AGO NERO OTTOBRE <eoln>
P PANE PERA <eoln>
A CASA <eoln><eof>
In questo caso non deve essere stampata alcuna parola.
Esempio del file “parole.txt”
M MONDO GARE <eoln>
O OCA POLLO <eoln>
P PANE SERA <eoln>
F GATTO <eoln><eof>
In questo caso devono essere stampate le parole: GARE, SERA, GATTO

Il problema è che non riesco a far fare tutti i confronti e cambiare lettera di riferimento quando si cambia riga.

Valeriodev
07-04-2008, 08:51
Ciao.
Forse ho capito male ma non mi sembra così difficile.
Apri il file,
Ogni linea la passi ad un metodo void,
questo metodo che prende in input quesa stringa la divide in un array in base a gli spazi e ti ritrovi nella posizione array[0] la lettera MAESTRA e negli altre posizioni le altre parole.
Scorri l'array con un for e per ogni parola con una substring controlli se la prima lettera della parola corrisponde con la MAESTRA(array[0]) e controlli anche l'ultima lettera se non corrisponde.
Per ogni condizione al FALSE stampi sennò esci dal metodo e continiu a leggere il file.
Scusa errori di grafia ma sto scappando che ho lezione ciao e spero di esserti stato di aiiuto!!!!

Skull260287
09-04-2008, 16:52
Originariamente inviato da Valeriodev
Ciao.
Forse ho capito male ma non mi sembra così difficile.
Apri il file,
Ogni linea la passi ad un metodo void,
questo metodo che prende in input quesa stringa la divide in un array in base a gli spazi e ti ritrovi nella posizione array[0] la lettera MAESTRA e negli altre posizioni le altre parole.
Scorri l'array con un for e per ogni parola con una substring controlli se la prima lettera della parola corrisponde con la MAESTRA(array[0]) e controlli anche l'ultima lettera se non corrisponde.
Per ogni condizione al FALSE stampi sennò esci dal metodo e continiu a leggere il file.
Scusa errori di grafia ma sto scappando che ho lezione ciao e spero di esserti stato di aiiuto!!!!

Grazie della risposta, in effetti ragionandoci a mente più fresca (non dico fresca perchè ultimamente non lo è mai!) in effetti non è molto difficile come algoritmo. Il fatto che è sto ancora capendo come gestire al meglio i file perchè ho iniziato a lavorarci da una settimana, prima non avevo fatto niente utilizzando file. Seguendo la tua proposta di utilizzare una procedura void, ho scritto un algoritmo basato sulla tua idea ma senza utilizzare substring ma semplicemente controllando, dopo averne memorizzato gli indici, la prima e l'ultima lettera di ogni parola, con la MAESTRA. Ecco il codice, fatemi sapere cosa ne pensate e come suggerite di modificarlo e perchè, tutte le critiche sono ben accette dato che ora sto imparando.




#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void controllo(string);

int main(){

ifstream file("parole1.txt");
char parole[100];
int i=0,ok=0;
if(!file){
file.open("parole1.txt");
cerr<<"Impossibile aprire il file parole1.txt"<<endl;
system("pause");
return -1;
}
while(!file.eof()){

file.getline(parole,100,'\n');
//cout<<parole<<endl;
controllo((string)parole);


}

system("pause");
return 0;
}

void controllo(string p){

int i=0,n=2;

while(p[n]!='\0'){
i=n;
//cout<<i<<endl;
while(p[n]!=' '){
n++;
}
if(p[i]!=p[0] &&p[n-1]!=p[0]){
for(int c=i;c<=(n-1);c++) cout<<p[c];
cout<<endl;
n++;
}
else n++;
}


}

XWolverineX
09-04-2008, 17:37
Non so se il tuo codice funziona, comunque io suggerirei

1) La funzione controllo fa in modo che prenda un char * e non una string (che poi il cast da char * a string è brutto solo a vedersi)

2) Nella funzione prendi la riga e spezzala nello spazio solo 1 volta tramite strtok.
3) Avrai la prima lettera nel puntatore ritornato da strtok: confrontalo con strcmp con le altre parole (che riceverai sempre tramite strtok).

shodan
09-04-2008, 19:26
Se utilizzi le std::string puoi usare le funzioni di ricerca che mette a disposizione.
Un'idea potrebbe essere questa.



//#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

void controllo(string);

int main(){

ifstream file("parole1.txt");
string parole;
int i=0,ok=0;
if(!file){
file.open("parole1.txt");
cerr<<"Impossibile aprire il file parole1.txt"<<endl;
system("pause");
return -1;
}
while(!file.eof()){

getline(file,parole); // si legge una riga intera
//cout<<parole<<endl;
controllo(parole);


}

system("pause");
return 0;
}

void controllo(string p){

string a,b,c;

// si divide nelle stringhe necessarie.
stringstream ss;
ss << p;
ss >> a;
ss >> b;
ss >> c;

// si utilizza la funzione find della std::string per trovare all'offset
// richiesto la stringa corrispondente (anche di un singolo carattere).
// se entrambe le condizioni sono false, si stampa la stringa richiesta.

if (b.find(a,0) == string::npos && b.find(a,b.size()-1) == string::npos) {
cout << b << endl;
}

if (c.find(a,0) == string::npos && c.find(a,c.size()-1) == string::npos) {
cout << c << endl;
}
}

Skull260287
16-04-2008, 16:25
Originariamente inviato da shodan
Se utilizzi le std::string puoi usare le funzioni di ricerca che mette a disposizione.
Un'idea potrebbe essere questa.


Ciao, grazie mille per la risposta, e scusa il ritardo nella mia replica. Da quello che ho capito, il codice che mi ha postato tu va bene se so a priori il numero delle parole contenute su ogni riga, o quantomeno il numero massimo delle parole di ogni riga, ma se questo varia da riga a riga e da file a file in ingresso non dovrebbe girare, o sbaglio?

shodan
16-04-2008, 17:25
In questo caso si.( Era solo un esempio :) ). Attenzione però che funziona solo se c'è lo spazio per dividere la parole, se cambia in virgola occore passare alla strtok od a un tokenizer più sofisticato. (Boost ne ha uno)

Se non sai quante parole ci sono su una linea, basta modificare un pò la funzione.



void controllo(string p){
// si divide nelle stringhe necessarie.
stringstream ss;
string a;
string b;
ss << p;
ss >> a; // contiene la stringa di un carattere.
while (!ss.eof()) {
b.erase();
ss >> b; // divide in stringhe
// si utilizza la funzione find della std::string per trovare all'offset
// richiesto la stringa corrispondente (anche di un singolo carattere).
// se entrambe le condizioni sono false, si stampa la stringa richiesta.

if (b.find(a,0) == string::npos && b.find(a,b.size()-1) == string::npos) {
cout << b << endl;
}
}
}

JamesC++
17-04-2008, 12:52
Se utilizzi la libreria std::string non ti dovrebbe rimanere difficile fare una funzione per il tuo problema.
Possiede il metodo capacity per vedere quanto è lunga una stringa quindi puoi immediatamente accedere al primo elemento della string e all'ultimo e fare i controlli necessari.

Spero di esserti stato utile..

Loading