Errore di segmentazione e gestione dei colori in C

di il
7 risposte

Errore di segmentazione e gestione dei colori in C

Buongiorno a tutti, stavo cercando di realizzare una personale versione del comando grep della shell di linux, con piu' parametri però.
Il codice principale (quello della ricerca se in una riga sono presenti tutti i parametri passati) funziona benone. Volevo però implementare la funzione --color la quale colora i parametri cercati.
Parlando del codice, dopo aver verificato che la riga contiene tutti i parametri che gli ho passato, ho inserito un metodo a cui passo: argc(il numero di parametri), argv(l'arrey dei parametri) e la stringa da stampare. Questo metodo dovrebbe restituire la stringa con tutti i parametri colorati.
Sono riuscito a estrarre le tre sotto-stringhe ossia la parte prima de parametro cercato, il parametro cercato, e la parte dopo il parametro cercato. Quando però cerco di aggiungere alla stringa del parametro cercato il codice del colore, mi da errore di segmentazione.
Qualcuno sa perchè?
Grazie in anticipo

int colorString(int nParam, char *param[], char str[])
{
	char *pointer; 
	
	char tem1[400] = "\0"; // Tiene la parte iniziale della stringa
	char *temp1 = tem1; // Tiene la parte iniziale della stringa
	
	char tem2[800] = "\0";// Tiene la parte del parametro della stringa
	char *temp2 = tem2;// Tiene la parte del parametro della stringa
	
	char tem3[400] = "\0";// Tiene la parte finale della stringa
	char *temp3 = tem3;// Tiene la parte finale della stringa
	
	char tem[1000] = "\0"; //Stringa di appoggio
	char *temp = tem;
		
	char colorEnd[9] = "\e[00m"; //Parte finale del codice dei colori
	char *color[8] = {"\e[1;31m", "\e[1;32m", "\e[1;33m", "\e[1;34m", "\e[1;35m", "\e[1;36m", "\e[1;37m"}; // Parte iniziale dei vari codici dei colori
	
	for(int i=2; i<nParam; i++)
	{
		pointer = strstr(str, param[i]);
		strcpy(temp2, param[i]);
		strcpy(temp3, pointer+strlen(param[i]));	//Estrazione delle sottostringhe
		strncpy(temp1, str, strlen(str)-(strlen(param[i])+strlen(tem3)));
		
		//QUI DA ERRORE 
		temp2 = strcat(color[0], temp2);
		temp2 = strcat(temp2, colorEnd);
		temp = strcat(temp1 , temp2);
		temp = strcat(temp , temp3);
		str = temp;
		if (strstr(tem3, param[i]) != NULL)
			sottoString(nParam, param, tem3); //Ricorsione
	}
	
	
	return 0;
}

7 Risposte

  • Re: Errore di segmentazione e gestione dei colori in C

    Devi rileggere strcat cosa fa.
    Non puoi concatenare in color[], perché oltre ad essere allocata in una posizione della memoria non modificabile, il buffer è pure troppo piccolo.

    strcat(destinazione, sorgente)
    Quindi
    
    char ciao[100] = "ciao";
    char due[100] = "due";
    strcat(ciao,due);
    puts(ciao);
    
    Come risultato darà
    
    ciaodue
    
  • Re: Errore di segmentazione e gestione dei colori in C

    Grazie mille, ho corretto questo errore.
    Purproppo ne è spuntato un altro: non riesco a modificare la stringa str dentro il metodo. Ritorna sempre nel main come gliela ho passata... Ho provato anche ad assegnarli una parola semplice come Ciao e a farla tornare nel main, ma niente da fare.
    Cosa sto sbagliando?

    Rinvio il codice aggiornato:
    
    void colorString(int nParam, char *param[], char str[])
    {
    	char *pointer; 
    	
    	char tem1[1000] = ""; // Tiene la parte iniziale della stringa
    	//char *temp1 = tem1; // Tiene la parte iniziale della stringa
    	
    	char tem2[1000] = "";// Tiene la parte del parametro della stringa
    	//char *temp2 = tem2;// Tiene la parte del parametro della stringa
    	
    	char tem3[1000] = "";// Tiene la parte finale della stringa
    	//char *temp3 = tem3;// Tiene la parte finale della stringa
    		
    	char colorEnd[9] = "\e[00m";
    	char *color[8] = {"\e[1;31m", "\e[1;32m", "\e[1;33m", "\e[1;34m", "\e[1;35m", "\e[1;36m", "\e[1;37m"};
    	
    	for(int i=2; i<nParam; i++)
    	{
    		pointer = strstr(str, param[i]);
    		strcpy(tem2, param[i]);
    		strcpy(tem3, pointer+strlen(param[i]));	//Estrazione delle sottostringhe
    		strncpy(tem1, str, strlen(str)-(strlen(param[i])+strlen(tem3)));
    		
    		if (strstr(tem3, param[i]) != NULL)
    			sottoString(nParam, param, tem3); //Ricorsione
    		
    		strcat(tem1, color[i-2]);
    		strcat(tem1, tem2);
    		strcat(tem1, colorEnd);
    		strcat(tem1 , tem3);
    		str="";
    		str = tem1;
    	}
    	
    	return ;
    }
  • Re: Errore di segmentazione e gestione dei colori in C

    Str è un puntatore; quello che puoi fare è modificare il contenuto puntato da str, con strcpy().
  • Re: Errore di segmentazione e gestione dei colori in C

    Probabilmente dovresti studiare bene le basi della gestione dei puntatori e delle stringhe prima di avventurarti in programmi simili.
  • Re: Errore di segmentazione e gestione dei colori in C

    Grazie mille dell'aiuto.
    Ho corretto anche questo errore.
    Stanamente a volte, sopratutto con stringhe di pochi caratteri, mi da ancora errore di segmentazione.
    Non capisco cosa possa essere.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    void sottoString(int nParam, char *param[], char str[])
    {
    	int i;
    	int u;
    	char *pointer; 
    	
    	char tem1[1000] = ""; // Tiene la parte iniziale della stringa
    	
    	char tem2[1000] = "";// Tiene la parte del parametro della stringa
    	
    	char tem3[1000] = "";// Tiene la parte finale della stringa
    	
    	char colorEnd[9] = "\e[00m"; //Vettore dei colori
    	char *color[8] = {"\e[1;31m", "\e[1;32m", "\e[1;33m", "\e[1;34m", "\e[1;35m", "\e[1;36m", "\e[1;37m"};
    	
    //**********************************************************************
    	
    	for(i=2; i<nParam; i++)//i=2 perchè i primi 2 parametri passati sono
    	{// il nome dell'eseguibile e il nome del file dove cercare
    		
    		for(u=0; u<1000; u++) //porto tem[1..3] a stringa vuota
    		{
    			tem1[u]='\0';
    			tem2[u]='\0';
    			tem3[u]='\0';
    		}
    		
    		pointer = strstr(str, param[i]); // punta alla prima occorrenza
    		// della sottostringa cercata
    		
    		//Estrazione delle sottostringhe
    		strcpy(tem2, param[i]);//tem2
    		strcpy(tem3, pointer+strlen(param[i]));	//tem3
    		strncpy(tem1, str, strlen(str)-(strlen(param[i])+strlen(tem3))); //tem1
    		
    		if (strstr(tem3, param[i]) != NULL)//ricorsione
    			sottoString(i+1, param, tem3); 
    
    		//Concatenazione sottostringhe
    		strcat(tem2, colorEnd);
    		strcat(tem2, tem3);
    		strcat(tem1, color[i-2]);
    		strcat(tem1, tem2);
    		
    		//Copia array
    		strcpy(str, tem1);
    	}
    	return ;
    }
    
    int IgnoraCase(int argc, char *argv[])
    {
    	if((argv[argc-1][0] == '-' || argv[argc-1][0] == '/' ) && argv[argc-1][1] == 'i') //Confronto l'ultimo parametro con "-i" o "/i"
    		return 0;
    		
    	return -1;
    	
    	}
    	
    void Help()
    {	
    	printf("\e[1;33m\t *** FindLog ***\e[00m\n\n");
    	printf("Uso: FindLog FILE_DI_LOG PARAMETRO_1 [PARAMETRO_2]... [PARAMETRO_7] [OPZIONE]\n");
    	printf("Cerca nel FILE uno o più PARAMETRO.\n\n");
    	printf("Opzioni:\n");
    	printf("   --help \tVisualizza questo aiuto ed esce\n");
    	printf("   -i     \tIgnora il case del FILE e del PARAMETRO\n");
    	printf("\n\n");
    	
    	return;
    	}
    
    int main(int argc, char *argv[]) {
    
    	char buf[1000];
    	char *res;
        int i;
        int j;
        int k;
        int righe = 0;
       
    //*************************************************************
    
    	if(argc == 1 || argc == 2 || strcmp(argv[argc-1], "--help") == 0){ //Se non sono stati passati parametri sufficienti 
    		Help();	// stampo il --help
    		exit (1);
    	}
    	
    //***************************************************************
    	
    	//CONTROLLO SE ESISTE IL FILE
    	FILE *fp = NULL;
    	fp = fopen(argv[1], "r");
    	if(fp == NULL)
    	{
    		printf("\e[1;31mErrore! File non riconosciuto !\e[00m\n");
    		exit(1);
    	}
    	
    //***************************************************************
    	
    	//CONTROLLO CASE
    	int caseCtrl; //Usato come un booleano 
    	
    	caseCtrl=IgnoraCase(argc, argv);
    	
    	if(caseCtrl == 0)
    		argc--;//se l'utimo parametro è l'ignora case
    		// diminuisco i parametri di 1
    		
    	
    	if(caseCtrl == 0)	//TO LOWER
    		for(j=2; j< argc; j++)
    			for(k=0; k< strlen(argv[j]); k++)
    				if(argv[j][k]>=65 && argv[j][k]<=90)
    					argv[j][k]+=32;
    //****************************************************************
    	
    	//CONTROLLO PARAMETRI
    	if(argc > 9)
    	{
    		printf("\e[1;31mErrore! Troppi parametri passati!\e[00m\n");
    		exit (1);
    		}
    		
    	for(i=2; i<argc; i++)
    	{
    		for(j=i+1; j<argc; j++)
    		{
    			if(strstr(argv[i], argv[j]) != NULL){
    				printf("\e[1;31mErrore! In un parametro è presente un altro parametro!\e[00m\n");
    				exit (1);
    				}
    			if(strstr(argv[j], argv[i]) != NULL){
    				printf("\e[1;31mErrore! In un parametro è presente un altro parametro!\e[00m\n");
    				exit (1);
    				}
    			}
    		}
    			
    //****************************************************************
    
    
    	printf("\e[1;33mSTART\e[00m\n");//stampo start
    
    	while(1) {
    		res=fgets(buf, 1000, fp);
    		if(caseCtrl == 0)	//TO LOWER
    			for(j=0; j<strlen(buf); j++)
    				if(buf[j]>=65 && buf[j]<=90)
    					buf[j]+=32;
    			
    		if( res==NULL )
    			break;
    		for(i=2; i < argc; i++)
    		{
    				if (strstr(buf, argv[i]) == NULL)//CONTROLLO SE NELLA STRINGA 
    				{// E' PRENSENTE LA SOTTOSTRINGA PASSATA
    					break;
    					}
    					
    				if (i == argc-1)
    				{	//SE LA STRINGA SUPERA TUTTI I CONTROLLI LA STAMPO
    					//printf("%s\n", buf);
    					sottoString(argc , argv, buf);
    					printf("%s\n", buf);
    					righe++; // Tengo conto del numero di righe
    					}
    		}
    	}
    	
    //*****************************************************************
    	
    	/* chiudo il file */
    	fclose(fp);
    	
    	printf("\e[1;34mEND\e[00m\n");//Stampo end
    	printf("\e[1;32mRighe totali : %i\e[00m\n", righe); //Stampo numero di righe
    		
    	return 0;
    }
  • Re: Errore di segmentazione e gestione dei colori in C

    Stanamente a volte, sopratutto con stringhe di pochi caratteri, mi da ancora errore di segmentazione.
    Non capisco cosa possa essere.
    Comincia con l'individuare il punto in cui avviene l'impiantamento; questo lo puoi a) utilizzando un debugger oppure b) inserendo delle printf() nei vari punti del programma per capire dove ti trovi al momento dell'errore.
  • Re: Errore di segmentazione e gestione dei colori in C

    Grazie mille dell'aiuto! Sono riuscito a trovare l'errore. Ora il programma funziona! Il problema era il buffer troppo corto, ora lo ho allungato un bel po'. Grazie a tutti!
Devi accedere o registrarti per scrivere nel forum
7 risposte