Newsgroup: it.comp.lang.c
Titolo: files & stringhe

Ciao a tutti. Vi chiederei un piccolo aiutino per risolvere un
problemino che mi sta facendo impazzire. Il programma deve (in ambiente
Linux):
1) aprire un file di testo (esempio piu' sotto, "behaviour.lst")
2) leggere tutte le stringhe che ci sono dentro
3) a seconda della stringa letta, deve operare alcune azioni.
Il problema non è la struttura, ma il fatto che non riesco a fare
funzionare correttamente
strcmp (*stringa1, * stringa2) e non riesco ad intercettare l'EOF. Se
qualcuno fosse cosi' gentile da segnalarmi una qualche soluzione, gliene
sarei molto grato.
Paolo
**************** file incriminato ***************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void load_bhv()
{
  int i;
  char * string;
  FILE * fd;
  fd = fopen("behaviour.lst", "r");
  i=0;
  while (  !feof(fd) )
    {
      printf("%d ",i++);
      fscanf(fd, "%s", string);
      printf("|%s|", string);
      if ( (strcmp( "BEGIN" , string) == 0 ))
   printf("E' iniziato un nuovo behaviour");
      /* E qui mi da un errore di segfault */
    }
  fclose(fd);
}
void main()
{
  load_bhv();
}
**************************************
************ behaviour.lst ***************
BEGIN calcia
CANDO:
  THR ( ball close AND ball north ) 0.9
TODO:
  kick
END
THATSALL
**************************************

 **************************************
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

 
  Il problema e' un altro: alla fscanf() devi passare un puntatore a 
  alla stringa da riempire. Tu hai dichiarato  
  char *string;
  quindi 'string' e' un puntatore a qualcosa di indefinito. 
  Dovresti invece dichiarare qualcosa  del tipo 
  char string[LunghezzaMassima];
  in questo modo 'string' punta a una zona di memoria su cui la fscanf()
  puo' andare a scrivere la stringa che legge dal file.
  Inoltre dovresti controllare che la fscanf() non torni zero (quando il file termina)
*fabio*

(string) che non e' inizializzato e non punta a niente.  Scrivendoci
Giusto; errore frequente nei principianti, e occasionalmente
(per distrazione) capita a tutti.  Purtroppo in C non ++ si e`
costretti a usare puntatori per le stringhe, che sono forse il
tipo di dati piu` importante di tanti, tanti programmi, compresi
anche quelli di tipico interesse per principianti.
Alex

 e non riesco ad intercettare l'EOF. 
L'EOF viene rilevato solo dopo che si tenta di leggere oltre
la fine del file, e non quando si legge l'ultimo carattere.
Quindi il ciclo non termina dopo aver letto l'ultima stringa,
ma solo dopo un'altra iterazione extra.
Una soluzione definitiva puo' essere quella di usare lex/yacc
o flex/bison invece di fare a mano tutto il parser.
	Mauro

Grazie per le risposte e per i consigli.
1) Stando a quello che mi suggerite, farei meglio ad usare il C++ invece
del C-e-basta.
Anche a me andrebbe meglio, ma non sono riuscito a trovare riferimenti
all'uso della classe "string" (se esiste una sorta di standard).
Per caso mi potreste suggerire dove cercare?
2) qualcuno mi puo' illuminare sul discorso dei parser ? (meglio, darmi
qualche puntatore_a, cosi' risparmiate anche voi un po' di tempo a
rispondere alle domande dei "newbies" ;-)
Thanx
Paolo

Paolo Meriggi (
flowe...@iol.it
) wrote:
[ snip ]
: #include <stdio.h>
: #include <stdlib.h>
: #include <string.h>
#define BUFFSIZE 256
: void load_bhv()
: {
:   int i;
:   char * string;
    ^^^^^^^^^^^^^
Questo e' solo un puntatore !!!
sostituisci con
    char buffer[BUFFSIZE];
    char *invio;
:   FILE * fd;
:   fd = fopen("behaviour.lst", "r");
    if (fd == NULL) {
	perror("fopen");
	exit(EXIT_FAILURE);
    }
:   i=0;
:   while (  !feof(fd) )
^^^^^^^^^^^^^^^^^^^^^^^^
Errore !
feof() e' diverso da 0 solo /dopo/ che e' stato letto un EOF.
:     {
:       printf("%d ",i++);
:       fscanf(fd, "%s", string);
                         ^^^^^^
:       printf("|%s|", string);
                       ^^^^^^
Ma string a cosa punta ?
:       if ( (strcmp( "BEGIN" , string) == 0 ))
              ^^^^^^
Non va bene se cerchi solo "BEGIN" ma la stringa che esamini
contiene anche altre cose...
:    printf("E' iniziato un nuovo behaviour");
:       /* E qui mi da un errore di segfault */
:     }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sostituisci il ciclo con
     while (fgets(buffer, sizeof(buffer), fd)) {
	      /* toglie il '\n' a fine stringa */
              if (invio = strchr(buffer, '\n'))
                     *invio = '\0';
              printf("%d |%s|", i++, buffer);
	      /* devi confrontare solo i primi 5 caratteri */
              if ((strncmp("BEGIN", buffer, 5) == 0))
                      printf("\t--> E' iniziato un nuovo behaviour");
	      printf("\n");
     }
     /* controlla se fgets ha dato errore */
     if (ferror(fd)) {
              perror("fgets");
	      exit(EXIT_FAILURE);
     }
:   fclose(fd);
: }
: void main()
  ^^^^       
Erroraccio ! ;)
int main()
: {
:   load_bhv();
    return 0;
: }
Spero di esserti stato utile.
Ciao ciao
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

rispondere alle domande dei "newbies" ;-)
Uno dei punti migliori per cominciare puo` essere PCCTS, e il
suo derivato/discendente ANTLR; comincia, magari, da:
 
http://www.mcs.net/~tmoog/pccts.html
e segui i vari opportuni link da qui.
Alex

 Paolo
Ciao Paolo
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/
       Search, Read, Discuss, or Start Your Own