Riga più lunga

streghettaalice
Ho qualche problemino con questo esercizio:
dato un file di testo devo individuare la riga più lunga:
#include <stdio.h>
#include <stdlib.h>
#define LEN_STR 100

int main(int argc,char *argv[])
{
 FILE *fp;
 int i;
 int max;
 int riga;
 char ch;
   char str[LEN_STR];
   char *lunga=(char *)malloc(200);
   int conta=0;
   
 
 
 
  if(argc!=2){
     fprintf(stderr,"usage :fstat filename\n");
	 exit(EXIT_FAILURE);
	 }
	 
	if((fp=fopen(argv[1],"r"))==NULL){
        fprintf(stderr,"Can't open \n");
        exit(EXIT_FAILURE);
    }




max=0;
		/*numero di righe*/
	while((fgets(str,sizeof(str),fp))!=NULL){ 
             if(  strlen(str)>max)
			 {
			    max=strlen(str);
				strcpy(lunga,str);
				}
   	   
	  
	   
	}
	

	
return 0;
	}
	

Risposte
apatriarca
Ma qual'è il problema? Il codice non compila? Compila ma non funziona? Funziona solo a volte? Con quale input? ...

claudio862
Il tuo programma funziona così com'è (includi però, vedi dopo), purché il file abbia righe lunghe al più 100 caratteri. Ti resta solo da stampare "max" e "lunga".
Se il file invece ha righe più lunghe, "fgets" legge comunque al massimo "LEN_STR" caratteri. Potresti semplicemente aumentare "LEN_STR". Oppure potresti leggere la riga pezzo per pezzo, però non ho abbastanza dimestichezza con l'I/O del C per sapere come fare.

Altri commenti:

L'indentazione. In questo, ma anche nel codice postato in altri thread, l'indentazione è assolutamente caotica e incomprensibile. Quando scrivi del codice, devi farlo con l'obiettivo principale che sia comprensibile ad altre persone (e che sia corretto, ovviamente).
La regola di base è che aumenti il rientro ogni volta che apri una parentesi graffa, e lo diminuisci ogni volta che ne chiudi una. E il numero di spazi deve essere sempre lo stesso (in genere 4 o 8). Eventualmente puoi usare anche le tabulazioni (che molti programmi convertono comunque in sequenze di spazi della giusta lunghezza).
Aumenta anche la spaziatura, per esempio separa operatori e variabili con uno spazio.
Il tuo programma indentato in modo migliore:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEN_STR 10000

int main(int argc,char *argv[])
{
    FILE *fp;
    int max;
    char str[LEN_STR];
    char *lunga = (char *)malloc(LEN_STR);

    if (argc != 2) {
        fprintf(stderr,"usage :fstat filename\n");
        exit(EXIT_FAILURE);
    }

    if ((fp = fopen(argv[1], "r")) == NULL) {
        fprintf(stderr, "Can't open \n");
        exit(EXIT_FAILURE);
    }

    max = 0;

    /*numero di righe*/
    while ((fgets(str, sizeof(str), fp)) != NULL) {
        if (strlen(str) > max) {
            max = strlen(str);
            strcpy(lunga, str);
        }
    }

    printf("Max length: %i\n", max);

    printf("Longest line: %s\n", lunga);

    return 0;
}



Usi nella stessa funzione due stringhe, una allocata staticamente (str) ed una allocata dinamicamente (lunga). Quella allocata staticamente esiste solamente all'interno della funzione (in questo caso "main"), mentre quella allocata dinamicamente esiste finché non la elimini esplicitamente chiamando "free".
Anche se in questo esercizio non è strettamente necessario, prendi l'abitudine di liberare la memoria che non serve più chiamando "free" non appena possibile.


Per usare le funzioni "strlen" e "strcpy" devi includere il relativo header . Se non lo fai il compilatore cerca di indovinare il tipo delle funzioni, ma potrebbe sbagliare. Nel caso migliore non riesci a compilare, nel caso peggiore avrai errori casuali durante l'esecuzione.

streghettaalice
è vero... e se invece devo determinare il numero massimo di carattere per riga e la media dei caratteri?
Io ho fatto così e va bene se non per l'ultima riga in cui mi da un numero di caratteri sballato,
perchè proprio l'ultima riga?
while((fgets(str,sizeof(str),fp))!=NULL){ 
   conta=0;
  
     for(i=0;str[i]!='\n';i++)//str[i] è carattere
	 {
	 
	   if(str[i]!=' ')
	    conta=conta+1;
		
		}
	   if(conta >max)
	   max=conta;
	   
	   
	   
	   
	   contaTot=contaTot+ conta; 
       contaRighe=contaRighe+1;	 
  
}

claudio862
Forse perché l'ultima riga non termina con '\n'. Prova a cambiare il ciclo for così:

for (i = 0; str[i] != '\n' && str[i] != 0; i++)

vict85
Secondo me non è necessario caricare tutto in questo modo, soprattutto considerando i limiti di dimensione e la gestione dei blocchi. Personalmente trovo possa essere più pratico leggere tutto carattere per carattere contandoli fino a che non trovi \n oppure EOF. A quel punto se è più lunga della precedente memorizzi la posizione iniziale della riga e il numero di righe. Alla fine allochi il numero di caratteri di cui hai bisogno e li stampi. Al fine di evitare crash non voluti puoi comunque settare un numero massimo di caratteri e stampare un errore se trova una riga troppo lunga.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.