Ordinamento date formato stringa in C89

di il
5 risposte

Ordinamento date formato stringa in C89

Salve a tutti,
Sto svolgendo un progetto per un esame universitario in C,precisamente usando lo standard C89, il mio programma deve ordinare una lista di clienti letti da un file secondo nome,cognome..ecc ecc...
Il mio problema adesso sono le date dovendo essere formate da specifiche di progetto da una sequenza di caratteri avente il formato GG/MM/AAAA dove:

GG è un intero che rappresenta il giorno
MM rappresenta il mese (Gen,Feb..)
AAAA intero di 4 cifre che rappresenta l'anno.
(all'interno del file da leggere)

la data è un record all'interno del file da leggere.

Io per rappresentare un cliente ho usato una struttura e per la data un campo char[] dentro la struttura...ma diventa difficile ordinarla visto che in C89 devo usare il confronto tra singoli caratteri e nn posso usare un intera stringa...

Qualcuno mi può dare una mano????

Grazie!

5 Risposte

  • Re: Ordinamento date formato stringa in C89

    In che senso non puoi usarla come stringa??
    Comunque innanzitutto ti consiglio (se puoi) di mettere la data in un unica stringa con formato AAAAMMGG in questo modo sei sicuro che con una normale STRCMP hai tutto ordinato correttamente..
    Strcmp è in <string.h> ma comunque questo è il codice:

    int StrCmp(char s1[], char s2[])
    {
    int i = 0;
    while (s1 != '\0' && s2 != '\0')
    if (s1 == s2)
    i++;
    else
    if (s1 < s2)
    return -1;
    else
    return 1;
    if (s1 != '\0')
    return 1;
    else if (s2 != '\0')
    return -1;
    else
    return 0;
    }
  • Re: Ordinamento date formato stringa in C89

    Ma questi clienti in che ordine vanno ordinati?
    e dopo averli ordinati che si deve fare?
  • Re: Ordinamento date formato stringa in C89

    Credo di aver terminato il programma.
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 15
    #define DATA 11
    
    struct cliente
    {
    	char nome[MAX];
    	char cognome[MAX];
    	char data[DATA];
    };
    
    enum Ordine
    {Nome,Cognome, Data};
    
    typedef enum Ordine Ordine;
    
    int ReadFile(char* path,struct cliente* cl);
    int WriteFile(char* path, struct cliente* cl, int len);
    int Ordina(struct cliente* cl, int len,Ordine ordine);
    int strcmp(char* str_a,char* str_b);
    int strcmpdata(char* data1,char* data2);
    int strlen(char* _source);
    void strcpy(char* _Dest,char* _source);
    
    int main(int argc, char * argv[])
    {
     struct cliente cl[MAX]={'\0'};
     struct cliente *ord;
     int len;
    
    	len = ReadFile("C:\\clienti.txt",cl);
    	Ordina(cl,len,Nome);
           //Ordina(cl,len,Cognome);
           //Ordina(cl,len,Data);
    
    	WriteFile("C:\\clientiordinati.txt",cl,len);
    	return 1;
    }
    
    ////////////////////////////////////////////
    //fileio
    int ReadFile(char* path,struct cliente* cl)
    {
     FILE *fp;
     int c,i=0;
    
    	fp = fopen(path,"r");
    	while((c=getc(fp))!=EOF)
    	{
    		ungetc(c,fp);
    		fscanf(fp,"%s\0",cl[i].nome);
    		fscanf(fp,"%s\0",cl[i].cognome);
    		fscanf(fp,"%s\0",cl[i++].data);
    	}
    	fclose(fp);
    	return i;
    }
    
    int WriteFile(char* path, struct cliente* cl, int len)
    {
     FILE *fp;
    
    	fp = fopen(path,"w");
    	for(int i=0;i<len;i++)
    	{
    		fprintf(fp,"%s ",cl[i].nome);
    		fprintf(fp,"%s ",cl[i].cognome);
    		fprintf(fp,"%s\n",cl[i].data);
    	}
    	fclose(fp);
    	return 1;
    }
    
    //////////////////////////////////////////////
    //stringhe
    int strlen(char* _source)
    {
     int i;
    
    	for(i=0;_source[i]!='\0';i++);
     
    	return i;
    
    }
    void strcpy(char* _Dest,char* _source)
    {
    	for(int i=0;i<strlen(_source);i++)
    		_Dest[i]=_source[i];
    }
    int strcmp(char* str_a,char* str_b)
    {
    	/*compara due stringhe, ritorna 0 nel caso le due stringhe 
    	sono uguali	ritorna 1 nel caso la prima stringa è alfabeticamente
    	minore della seconda, ritorna -1 altrimenti.*/
    
     int i=0;
    
    	for(i=0;str_a[i]==str_b[i] && str_a[i]!='\0' && str_b[i]!='\0';i++);
    
    	if (str_a[i]==str_b[i])
    		return 0;
    	else if (str_a[i]<str_b[i])
    		return 1;//la prima stringa viene prima
    	else
    		return -1;//la seconda stringa viene dopo
    }
    
    int strcmpdata(char* data1,char* data2)
    {
    	/*la funzione compara due date, ritorna 0 se le date sono uguali,1 se la prima data è
    	maggiore della seconda, 2 se la seconda data è maggiore della prima, -1 se il valore
    	di una delle due date è errato*/
    
      int mese=0,anno=0,giorno=0,i=0;
    
    	giorno = atoi(data1);
    		if (giorno>31 || giorno<1) return -1;
    		
    	mese =atoi(&data1[3]);
    		if (mese>12 || mese <1)return -1;
    		
    		anno =atoi(&data1[6]);
    
    		if(anno==atoi(&data2[6]))
    			if(mese==atoi(&data2[3]))
    				if (giorno==atoi(data2))
    					return 0;
    				else if(giorno>atoi(data2))
    					return 1;
    				else
    				{
    					if (atoi(data2)>31 || atoi(data2)<1) return -1;				
    					return 2;
    				}
    			else if (mese>atoi(&data2[3]))
    				return 1;
    			else {
    				if (atoi(&data2[3])>12 || atoi(&data2[3]) <1)return -1;
    				return 2;
    			}
    		else if (anno>atoi(&data2[6]))
    			return 1;
    		else
    			return 2;
    }
    
    ///////////////////////////////////////////////////////
    ///ordinamento
    void Scambio(struct cliente* _a,struct cliente* _b)
    {
    	struct cliente tmp = *_b;
    	*_b = *_a;
    	*_a = tmp;
    }
    
    int Ordina(struct cliente* cl,int len,Ordine ordine)
    {
    	/*la funzione ritorna una struttura avente gli elementi
    	della struttura passata in input ordinati per nome */
    	
    	
    	for(int i=0;i<len;i++)
    		for(int n=i+1, c;n<len;n++)
    		{
    			switch (ordine)
    			{
    				case Nome:
    					if(strcmp(cl[i].nome,cl[n].nome)==-1)
    						Scambio(&cl[n],&cl[i]);
    						break;
    				case Cognome:
    					if(strcmp(cl[i].cognome,cl[n].cognome)==-1)
    						Scambio(&cl[n],&cl[i]);
    						break;
    				case Data:
    					if(c=strcmpdata(cl[n].data,cl[i].data)==2)
    					{
    						Scambio(&cl[n],&cl[i]);
    						break;
    					}
    					else if(c==-1)
    						return -1;
    			}
    		}
    	return 1;
    }
    
    legge da file e salva nell'array di struttura cliente. Poi ordina con la funzione Ordina() che ha come parametri, il puntatore alla struttura cliente, la lunghezza e un enum, che indica il tipo di ordine. Acceta valori
    Nome Cognome e Data, rispettivamente per ordinare la struttura per Nome, cognome e data.

    Non conoscendo lo standard C89, ho creato le funzione per la gestione delle stringhe come la strcpy, strlen e la strcmp che compara due stringhe, mentre la strcmpdata compara due date.
    strcmpdata:
    
    int strcmpdata(char* data1,char* data2)
    {
       /*la funzione compara due date, ritorna 0 se le date sono uguali,1 se la prima data è
       maggiore della seconda, 2 se la seconda data è maggiore della prima, -1 se il valore
       di una delle due date è errato*/
    
      int mese=0,anno=0,giorno=0,i=0;
    
       giorno = atoi(data1);
          if (giorno>31 || giorno<1) return -1;
          
       mese =atoi(&data1[3]);
          if (mese>12 || mese <1)return -1;
          
          anno =atoi(&data1[6]);
    
          if(anno==atoi(&data2[6]))
             if(mese==atoi(&data2[3]))
                if (giorno==atoi(data2))
                   return 0;
                else if(giorno>atoi(data2))
                   return 1;
                else
                {
                   if (atoi(data2)>31 || atoi(data2)<1) return -1;            
                   return 2;
                }
             else if (mese>atoi(&data2[3]))
                return 1;
             else {
                if (atoi(&data2[3])>12 || atoi(&data2[3]) <1)return -1;
                return 2;
             }
          else if (anno>atoi(&data2[6]))
             return 1;
          else
             return 2;
    }
    
  • Re: Ordinamento date formato stringa in C89

    Ragazzi vi ringrazio infinitamente per il vostro aiuto, i vostri suggerimenti sono stati molto utili!!!

    Overflow ho modificato il tuo codice alle mie esigenze ed adesso funziona perfettamente!!!
    Anche se ho dovuto fare una "porcata" assurda perchè due date ostinavano a non ordinarsi...ma adesso ho risolto tutto.

    Adesso mi manca solo di curare la scelta dell'ordinamento e del campo di ordinamento (che deve essere fatto da shell ) e modificare le mie funzioni per l'ordinamento discendente...poi il grosso del lavoro e fatto...devo solo aggiungere delle "finezze" tipo gestire eventuali errori di immissione e campi errati!!!

    Spero di poter contare ancora sul vosto aiuto!!!

    lokhii.
  • Re: Ordinamento date formato stringa in C89

    Ciao, sono contento che i nostri aiuti ti sono serviti.
    Volevo solo chiederti se hai avuto problemi con la funzione strcmpdata per confrontare due stringhe.
    E con quali date hai avuto problemi, cosi posso correggerla.
Devi accedere o registrarti per scrivere nel forum
5 risposte