PDA

Visualizza la versione completa : [C++] Array multidimensionale per lettura di stringhe


World_emp
29-08-2009, 02:43
Salve a tutti, sono nuovo da queste parti. Devo creare un programma per un lavoro di concordanza su un testo. Per la distinzione delle parole ho scelto di registrarle "carattere per carattere" in un array bidimensionale, dato che le funzioni che leggono automaticamente le stringhe si basano sugli spazi e i return per definire l'inizio e la fine di una parola, e per il mio lavoro è un procedimento troppo primitivo. Ho cominciato a fare un programma, ma riesco solo a registrare la PRIMA parola di un testo nell'array, in poche parole non sono riuscito a creare un ciclo che prosegue il lavoro per tutte le parole. Se poteste dirmi dove sbaglio mi fareste un grande favore. Grazie.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> /*ispunct()*/

main()
{
FILE *fp;
char ch, parole[1000][20]; /*parole[i][j]*/
int i, j;
fp=fopen("1","r");
ch = fgetc(fp);

if(fp==NULL)
{
printf("Non rieso ad aprire il file\n");
exit(1);
}

for(i=0; (i < 10) && (feof(fp) == 0); i++) /* Il seguente passaggio identifica una parola all'interno del testo ** passando carattere per carattere e la aggiunge ad un elemento dell'array */

for(j=0; (j < 20) && (feof(fp) == 0); j++) /*Leggere carattere per carattere*/
{
if(ispunct(ch) || isspace(ch)) /*Ferma il ciclo se il carattere è uno spazio o un punto*/
break;
parole[i][j] = ch;
ch = fgetc(fp);
}

parole[i][j] = '\0'; /*Terminatore della parola, senza fa casini (riserva sempre spazio fino al 20)*/
}

frankitt
29-08-2009, 11:22
Penso che l' errore sia proprio questa istruzione:

parole[i][j] = '\0';

In quanto se non sbaglio, essendo questo vettore una porzione contigua di celle (20000 nel tuo caso), se tu metti questa istruzione se tu salvi la prima parola, che per esempio è lunga 5, tu dici che questa stringa di 20000 caratteri terminerà alla 5 lettera. Quindi libereresti tutti i caratteri rimanenti e non li ritroveresti all' iterazione successiva, perchè il vettore è stato ridotto.

Quindi la cosa più semplice è allocare un vettore lungo quanto lo spazio del file (se il file è di 2000 byte, tu dichiari un char vector[2000]), salvi il file in una stringa e poi ti scansioni tutta questa stringa. Credo che poi fatto questo basti fare un ciclo con uno 'sscanf' per prelevare la stringa e poi 'sprintf' per salvarla dentro ogni stringa del vettore parole[1000][20].

Così credo che funzioni.

Ciao!

World_emp
29-08-2009, 12:17
Grazie per la risposta così rapida, ma non ho capito bene come riesco a scandire carattere per carattere di una parola con la funzione sscanf, controllare se sono punti o spazi (con isspunct() e isspace()), e aggiungere le singole parole nel mio array bidimensionale. :S

frankitt
29-08-2009, 12:42
Allora per lo sscanf non l' ho mai usato, però dovretsi usare qualcosa del genere:




while(stringa[i]!='\0') {

sscanf(&stringa[i],"%s",parola);

i += strlen(parola);

}



qualcosa del genere...

Altrimenti potresti vedere bene come funzioni la strtok, che è una funzione che toglie i caratteri che tu vuoi dalla stringa.
quindi potresti usare strtok su ogni parola che crei.
Ti ricordo che la fuzione di prima è un abbozzo. Però è importante che tu abbia capito il meccanismo.
Ora sta a te vedere come far funzionare insieme o separatamente sscanf o strtok.

CIAO!

World_emp
29-08-2009, 13:19
Ho scoperto che il problema di fgetc() è che quando interrompo il ciclo continua a leggere lo stesso carattere, quindi ho provato a fare "spostare" fgetc() di uno ogni volta che incontra uno spazio o un punto con l'indicazione ch += 1 questo però mi da un output strano, per la frase "sono andato al parco" mi restituisce:

$ ./a.out
sono
0parco



for(i=0; (i < 10) && !feof(fp); i++)

/* Il seguente passaggio identifica una parola all'interno del testo
** passando carattere per carattere e la aggiunge ad un elemento dell'array */
for(j=0; (j < 20) && !feof(fp); j++) /*Leggere carattere per carattere*/
{
if(ispunct(ch) || isspace(ch)) /*Ferma il ciclo se il carattere è uno spazio o un punto*/
{
ch += 1;
continue;
}
parole[i][j] = ch;
ch = fgetc(fp);
}
fclose(fp); /* chiude il file */

printf("\n");
printf("\n%s", parole[0]);
printf("\n%s", parole[1]);
printf("\n%s", parole[2]);
}

frankitt
30-08-2009, 11:40
Da quel che ho capito, tu se incontri un caratteri tipo ,.; passi alla parola successiva.
Se così è non devi usare continue bensì break, perchè tu devi uscire dal ciclo più interno, e poi passare al ciclo successivo del primo for, ovvero passare alla parola successiva. Così non lo stai facendo...per me ti conviene salvare tutto in una stringa e poi lavorare sulle stringhe è molto più semplice...

Loading