Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 21

Discussione: [C] Lettura da file

  1. #1

    [C]lettura da file

    Ciao a tutti. Ho problemi con la lettura di un file. Non posso utilizzare fopen fgets e compagne perchè il professore dice che non sono system calls... devo aprire il file con la "open". Il file in questione contiene caratteri e \n, cioè in poke parole quando ci scrivo scrivo la stringa e metto \n per far andare a capo. Come faccio a leggere riga per riga non sapendo quanti byte passare alla read poichè non so quanto è lunga una riga? Ho pensato di leggere char a char fino a trovare \n, ma se implemento una funzioncina che faccia questo ho segmentation fault. il codice della fiunzioncina è:

    char* leggiLinea(int fd)
    {
    char* stringa;
    char char_letto[1];
    stringa = "";
    do
    {
    read(fd, char_letto, sizeof(char));
    strcat(stringa, char_letto);
    } while ( strcmp(char_letto, "\n") == 0 );
    return stringa;
    }

    ovviamente quando la chiamo il file è già aperto, e ho allocato memoria per la stringa. Cosa c'è che non va?
    E inoltre, come faccio a farmi restituire NULL se il file pointer è alla fine del file e la funzione tenta di leggere?
    grazie ciao

  2. #2

    Re: [C]lettura da file

    Originariamente inviato da Fustaccio
    char* leggiLinea(int fd)
    {
    char* stringa;
    char char_letto[1];
    stringa = "";
    do
    [...]
    Non puoi assegnare "" ad un puntatore (stringa). Prova a mettere *stringa=""; oppure strcpy(stringa,""); anche se non sono belli all'apparenza dovrebbero fare al caso tuo.

    In ogni caso credo che sia inutile. anche eliminando tale riga il compilatore dovrebbe far girare il tutto correttamente...


  3. #3
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352

    Re: Re: [C]lettura da file

    Originariamente inviato da Ephestus
    Non puoi assegnare "" ad un puntatore (stringa)
    L'assegnazione è valida: un puntatore può puntare ad un letterale stringa.

    L'errore sta in:

    strcat(stringa, char_letto);

    qui: http://www.cplusplus.com/ref/cstring/strcat.html

    pui leggere la documentazione della funzione strcat. Questa funzione appende la seconda stringa alla prima passata come argomento, che deve già avere lo spazione suffiente a contenere la seconda. Quindi è necessario che la prima stringa sia:

    1 - un array grande abbastanza: char stringa[100] che prima della concatenzazioe contiene una stringa con meno di 99 caratteri e quindi c'è ancora spazio per aggiungere caratteri

    2 - oppure un puntatore ad un blocco di memoria allocato dinamicamente con malloc, conla stessa condizione di prima.

    Ma se tale blocco di memoria o array deve essere grande abbastanza da rendere possibile la concatenazione significa che già a priori dovresti sapere la dimensione totale della riga da leggere e quindi siamo allo stesso problema iniziale.

    Ciò che puoi fare è:

    - utilizzre un array sufficientemente grande che sai gia a priori potrà contenere la riga e utilizzare la fgets che legge fino al prossimo carattere di fine linea:

    http://www.cplusplus.com/ref/cstdio/fgets.html

    è necessario che l'array che le passi sia grande a sufficiente per contenere tutti i caratteri dell a riga che viene comuinque individuata dalla funzione, quindi te non devi preoccuparti di trovare il carattere di fine linea;

    - oppure scorrere la riga leggendo caratteri fino al prossimo \n, quindi allocarti un array di quella dimensione, tornare indietro nel file e leggere la riga con fread o fgets. Ciò è utile per leggere righe di qualsiasi dimensione nel caso non hai idea di quanto possano essere lunghe.

    In c++ si puo fare piu facilmente.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  4. #4
    Grazie per le risposte. Purtroppo però non posso utilizzare la fgets (perchè il prof NON VUOLE). Se avessi potuto invece di aprire con open, avrei aperto con fopen e tutti i miei problemi, sia di lettura che di scrittura non sarebbero esistiti(x es devo ogni volta che scrivo concatenare "\n" alla fine). Ho eliminato
    stringa = "" e ho modificato il codice in questo modo.
    Vi ricordo che quando chiamo questa funz ho allocato già sufficiente memoria per il valore di ritorno e ho già aperto il file a dovere.

    char* leggiLinea(int fd)
    {
    char* stringa;
    char char_letto = (char*) malloc (sizeof(char)+1)
    if (read(fd, char_letto, sizeof(char) == -1))
    return NULL;

    stringa = strcpy(stringa, char_letto);
    while (strcmp (char_letto, "\n") != 0)
    {
    read(fd, char_letto, sizeof(char));
    stringa = strcat(stringa, char_letto);
    }
    free char_letto;
    return stringa;
    }
    purtroppo compila, ma il risultato non è quello sperato. mi legge soli due caratteri e basta. AIUTOOOOOO

  5. #5
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    if (read(fd, char_letto, sizeof(char) == -1))

    è errato , dovrebbe essere

    if (read(fd, char_letto, sizeof(char)) == -1)

    attento alla parentsi...

    Inoltre la read legge solo un carattere, non appende un termnatore di stringa al carattere letto.

    Quindi il while

    while (strcmp (char_letto, "\n") != 0)

    dovresti trasformarlo in

    while (char_letto != '\n')

    Inoltre devi fermarti quando hai raggiunto la fine del file; quindi devi teenrti in una variabile il numero di byte letti restituito dalla read; l'altro errore è che non ti allochi la stringa, inoltre char_letto non è necessario che sia un puntatore a un char, puo esere un semplice char e poi passi alla read il puntore alla variabile:

    codice:
    char* leggiLinea(int fd){
         //alloco un buffer per contenere stringhe di al massimo
         //255 caratteri
         char* stringa = (char *)malloc(256 * sizeof(char));
         char char_letto = '\0';
    
         //invoco la read passando il puntatore al carattere
         int bytes_letti = read(fd, &char_letto, sizeof(char));
         //se c'è errore nella lettura
         if(bytes_letti == -1)
              return NULL;
         int posizione_corrente = 0;
         //continuo a leggere finchè non trovo il carattere di
         //fine linea o finchè non raggiungo la fine del file
         while((char_letto != '\n') && (bytes_letti > 0)){
              //metto il carattere letto nella stringa
              stringa[posizione_corrente] = char_letto;
              posizione_corrente++;
              bytes_letti = read(fd, &char_letto, sizeof(char));
         }
         //se c'è stato errore ritorno null
         if(bytes_letti == -1){
             //istruzione per deallocare stringa
              free(stringa);    
              return null;
         }
         //aggiungo il terminatore di fine stringa
         stringa[posizione_corrente] = '\0';
         return stringa;
    }
    Il codice non l'ho provato perche non sono sotto linux.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  6. #6
    Ti ringrazio molto per la disponibiltà Anx, purtroppo con questa soluzione il thread che la esegue si blocca proprio quando la sta chiamando, cosa che prima non mi era mai successa. Non so davvero da cosa può dipendere... certo il C, rispetto a java a cui mi hanno sempre abituato nei miei primi corsi, dà molti + grattacapi... :master:

  7. #7
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    metti delle istruzioni di stampa cosi mi dici qualìè lìistruzione precisa in cui si blocca

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  8. #8
    L'istruzione precisa è proprio quella in cui per la prima volta nel codice invoco la funzione in questione.
    All'inizio ho dichiarato una variabile
    char* stringa_letta;
    poi a un certo punto faccio:

    stringa_letta = leggiLinea(fd);

    (ovviamente il file è già stato aperto in O_RDWR

    per stringa_letta ho provato sia ad allocare memoria sufficiente prima di fare l'assegnazione, sia a non allocare memoria (pensando che cmq la stringa è già nella memoria allocata nella funzione e io ci assegno solamente il nuovo puntatore stringa_letta).

    Ho messo istruzioni di stampa anche dentro la funzione: esegue fino a int posizione_corrente = 0.
    Poi il flusso si interrompe, non entra a quanto pare nel ciclo (dove pure ho messo istruzioni di stampa).


  9. #9
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    metti un'istruzione di stampa prima di ogni istruzione presente nel while per capire se si ferma nel while o prima di esso. Poi magari posta il programma completo, o almeno un programma compelto funzionante con un main pronto da compilare ed esere provato.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  10. #10

    Re: Re: Re: [C]lettura da file

    Originariamente inviato da anx721
    L'assegnazione è valida: un puntatore può puntare ad un letterale stringa.
    Vergogna che sale

    Ne ero proprio convinto...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.