IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Algorithme de récupération


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Institut national supérieur des sciences et techniques d'Abéché
    Inscrit en
    Juin 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tchad

    Informations professionnelles :
    Activité : Institut national supérieur des sciences et techniques d'Abéché

    Informations forums :
    Inscription : Juin 2018
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Algorithme de récupération
    Bonjour, j'ai ces types de textes :

    SoDa_MERRA2_lat8.567_lon16.083_Logone-Occidental_Moun
    SoDa_MERRA2_lat8.663_lon16.854_Logone-Oriental_Do
    SoDa_MERRA2_lat8.913_lon17.554_Mandoul_Koum
    SoDa_MERRA2_lat9.143_lon18.392_Moyen-Chari_Sar
    SoDa_MERRA2_lat9.364_lon14.904_Moyo-Kebbi-Ouest_Pal
    SoDa_MERRA2_lat9.397_lon16.301_Tandjile_Lai
    SoDa_MERRA2_lat10.281_lon15.372_Mayo-Kebbi-Est_Bongo
    SoDa_MERRA2_lat11.029_lon20.283_Salamat_Am-Timan
    SoDa_MERRA2_lat11.404_lon16.170_Chari-Baguirmi_Massen
    SoDa_MERRA2_lat12.107_lon15.044_Ville-de-NDjamena_NDjamena
    SoDa_MERRA2_lat12.184_lon18.693_Guera_Mongo
    SoDa_MERRA2_lat12.225_lon21.410_Sila_Goz-Beïda
    SoDa_MERRA2_lat12.996_lon15.729_Hadjer-Lamis_Massako
    SoDa_MERRA2_lat13.215_lon18.335_Batha_Ati
    SoDa_MERRA2_lat13.459_lon14.715_Lac_Bol
    SoDa_MERRA2_lat13.641_lon16.489_Barh-el-Ghazel_Mousso
    SoDa_MERRA2_lat13.829_lon20.832_Ouaddai_Abech
    SoDa_MERRA2_lat14.121_lon15.310_Kanem_Mao
    SoDa_MERRA2_lat14.528_lon20.927_Wadi-Fira_Biltine
    SoDa_MERRA2_lat17.185_lon21.581_Ennedi-Ouest_Fada
    SoDa_MERRA2_lat17.750_lon23.167_Ennedi-Est_Am-Djarass
    SoDa_MERRA2_lat17.926_lon19.104_Tibesti_Faya
    SoDa_MERRA2_lat18.250_lon18.500_Borkou_Bourkou
    Comment écrire un programme en C, qui peut me permettre de récupérer les noms des villes, lat et lon dans une matrice comme celle-ci :

    Villes lat lon
    Moun 8.567 16.083
    Do 8.663 16.854
    Koum 8.913 17.554
    Sar 9.143 18.392
    Pal 9.364 14.904
    Lai 9.397 16.301
    Bongo 10.281 15.372
    Am-Timan 11.029 20.283
    Massen 11.404 16.170
    NDjamena 12.107 15.044
    Mongo 12.184 18.693
    Goz-Beïda 12.225 21.410
    Massako. 12.996 15.729
    Ati 13.215 18.335
    Bol 13.459 14.715
    Mousso 13.641 16.489
    Abech 13.829 20.832
    Mao 14.121 15.310
    Biltine 14.528 20.927
    Fada 17.185 21.581
    Am-Djarass 17.750 23.167
    Faya 17.926 19.104
    Bourkou 18.250 18.500

    Vos aides et orientations seront les bienvenues merci d'avance.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Cette entrée de la FAQ pourrait t'aider : https://c.developpez.com/faq/?page=S...-une-structure

  3. #3
    Membre chevronné
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 333
    Points : 1 828
    Points
    1 828
    Par défaut
    Bonjour,

    Ce que tu cherches c'est de parser ta chaine. Tu peux notamment t'en sortir avec strtok.(avec comme délimiteur '_'). Pour la latitude et la longitude tu dois juste enlever 3 caractères (car sizeof("lon")==sizeof("lat")==3).

    Dis nous si tu as des soucis pour appliquer cette méthode,

    Bonne journée.

    Edit: grillé

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par emixam16 Voir le message
    car sizeof("lon")==sizeof("lat")==3)
    Hop hop hop !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    #include <string.h>
     
    int main() {
        size_t s1 = sizeof("lon");
        size_t s2= sizeof("lat");
        printf("sizeof %lu %lu %lu\n", s1, s2);
     
        size_t l1 = strlen("lon");
        size_t l2= strlen("lat");
        printf("strlen %lu %lu\n", l1, l2);
    }
    sizeof 4 4 8
    strlen 3 3


  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Koumato Voir le message
    Vos aides et orientations seront les bienvenues merci d'avance.
    1. fgets() pour récupérer une ligne et la stocker dans une chaine
    2. strtok_r() pour découper une chaine (il s'agit bien évidemment de la chaine mentionnée à l'étape précédente !!!) sur un séparateur particulier (au hasard: l'underscore ?). A ce sujet strtok() mentionné par emixam16 fonctionnera toutefois je préfère préconiser de façon plus générale strtok_r() car cette dernière est réentrante (elle peut travailler par exemple sur plusieurs niveaux pour, par exemple, découper un PATH sur le ":" dans une première boucle puis, découper chaque chemin extrait sur le "/" dans une seconde pour récupérer les divers dossiers ; chose que ne permet pas strtok() qui travaille avec une variable statique laquelle ne permet alors qu'un seul niveau de découpage)
      Il faut bien entendu lire la doc de strtok_r() pour savoir s'en servir car on doit l'appeler plusieurs fois pour traiter toute la chaine. Donc il lui faut un moyen pour qu'elle sache à quel appel elle en est. Ainsi, au premier appel il faut lui passer la chaine originelle mais aux autres il faut lui passer NULL pour qu'elle comprenne qu'elle doit continuer son travail sur la fin du travail précédent. Et il faut lui passer l'adresse d'un pointeur qui lui sert à mémoriser son travail en cours pour pouvoir y revenir à l'appel suivant.
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      #include <stdio.h>
      #include <string.h>
       
      int main() {
      	char chaine[]="Hello:World:I'm here for a long time !!!";
      	char *work=NULL;
      	char *res;
       
      	while ((res=strtok_r(work != NULL ?NULL :chaine, ":", &work)) != NULL)
      		printf("res=[%s], work=[%s]\n", res, work);
      }
      Donc là, j'utilise le fait que "work" (qui sera modifié à chaque fois par la fonction) est initialisé à NULL pour détecter si je suis au premier appel ou pas.

    Et une fois que tu as en main les divers éléments, tu peux soit générer ton fichier output, soit le stocker dans un tableau de structures comme indiqué par Bktero ce qui, du fait de la dimension horizontale d'une structure multiplié par la dimension verticale d'un tableau donnera au final la matrice demandée.



    Citation Envoyé par Bktero Voir le message
    sizeof 4 4 8
    strlen 3 3
    Ben...euh... dans l'absolu tu montres qu'il avait raison ... ici sizeof("lat") est bien égal à sizeof("lon")...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Tu as sans doute lu un peu vite et raté le ==3 à la fin

    Je vois que vous êtes 2 à parler de strtok() et je ne vois pas du tout l'intérêt. Le fichier est formaté, c'est un boulot pour fscanf()... J'ai fait un essai avec une ligne (et donc j'ai utilisé sscanf() mais ça ne change pas grand chose). Ca marche très bien (et je me suis pas cassé la tête, j'ai strchr() mais en creusant un peu on doit pouvoir trouver le bon formatage) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <stdio.h>
    #include <assert.h>
    #include <string.h>
     
    const char* record = "SoDa_MERRA2_lat18.250_lon18.500_Borkou_Bourkou";
     
    int main() {
    	float lat = 0.0f;
    	float lon = 0.0f;
    	char location[1024] = {0};
    	int n = sscanf(record, "SoDa_MERRA2_lat%f_lon%f_%s", &lat, &lon, location);
    	assert(n == 3);
     
    	const char* city = strchr(location, '_') + 1;
    	printf("result: %s (%s) %f %f\n", city, location, lat, lon);
    }
    result: Bourkou (Borkou_Bourkou) 18.250000 18.500000

  7. #7
    Membre chevronné
    Avatar de emixam16
    Homme Profil pro
    Chercheur en sécurité
    Inscrit en
    Juin 2013
    Messages
    333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Chercheur en sécurité

    Informations forums :
    Inscription : Juin 2013
    Messages : 333
    Points : 1 828
    Points
    1 828
    Par défaut
    Oulah oui, je suis fatigué; j'ai écrit n'importe quoi. La taille est évidemment de 4 caractères en incluant le '\0' terminal. Je voulais juste dire qu'il faut faire un décalage de 3 octets dans la chaine pour lire la donnée. Mes excuses les plus plates pour cette imprécision .

    Pour le reste, les deux solutions marchent sans difficulté pour ce cas précis. Pour moi, aucune des deux n'est largement meilleure, donc cela dépend des préférences de chacun!

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Tu as sans doute lu un peu vite et raté le ==3 à la fin
    Oups...

    Citation Envoyé par Bktero Voir le message
    Je vois que vous êtes 2 à parler de strtok() et je ne vois pas du tout l'intérêt. Le fichier est formaté, c'est un boulot pour fscanf()... J'ai fait un essai avec une ligne (et donc j'ai utilisé sscanf() mais ça ne change pas grand chose). Ca marche très bien (et je me suis pas cassé la tête, j'ai strchr() mais en creusant un peu on doit pouvoir trouver le bon formatage) :
    Oui. J'ai du mal à penser scanf de moi même. Probablement traumatisé par toutes les merdes que j'ai eu avec cette fonction quand je ne la connaissais pas assez bien. Mais t'as raison, dans ce cas, c'est effectivement plus adéquat. strtok() sera plutôt à utiliser dans le cadre d'une chaine avec nb de champs non prévisible.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    J'ai cherché un peu et j'ai trouvé la bonne commande. J'ai même fait ça sur un fichier. Si ça peut servir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
     
    int main() {
    	FILE* file = fopen("data.txt", "r");
    	assert(file != NULL);
     
    	while (1) {
    		float lat = 0.0f;
    		float lon = 0.0f;
    		char city[1024] = {0};
    		int n = fscanf(file, "SoDa_MERRA2_lat%f_lon%f_%*[^_]_%[^\n]\n", &lat, &lon, city);
     
    		if (n == 3) {
    			printf("%s %f %f\n", city, lat, lon);
    		} else {
    			break;
    		}
    	}
    }
    Je vais donner quelques explications sur le format quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "SoDa_MERRA2_lat%f_lon%f_%*[^_]_%[^\n]\n"
    On a plusieurs récupérations de champs :
    • %f pour récupérer la latitude
    • %f pour récupérer la longitude
    • %*[^_] lit tous les caractères jusqu'à rencontrer _ (c'est le sens de [^_] : "tout sauf _") et jette le résultat de la conversion (c'est le sens de l'étoile *)
    • %[^\n] lit touts les caractères jusqu'à rencontrer \n (et ne jette pas le résultat de la conversion cette fois) pour obtenir le nom de la ville

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    J'ai cherché un peu
    Et voilà. Pas besoin de chercher avec strtok()

    Citation Envoyé par Bktero Voir le message
    Je vais donner quelques explications sur le format quand même :
    Oui, ça me semble utile effectivement

    Citation Envoyé par Bktero Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (n == 3) {
    	printf("%s %f %f\n", city, lat, lon);
    } else {
    	break;
    }
    Rhooo !!!
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (n != 3) {				// Personnellement je ne mets pas d'accolades dans ce cas précis mais pour te faire plaisir...:D
    	break;
    }
    printf("%s %f %f\n", city, lat, lon);
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Formalisation graphique des algorithmes
    Par David R. dans le forum Algorithmes et structures de données
    Réponses: 14
    Dernier message: 08/12/2012, 10h21
  2. Algorithme de randomisation ... ( Hasard ...? )
    Par Anonymous dans le forum Assembleur
    Réponses: 8
    Dernier message: 06/09/2002, 14h25
  3. recherches des cours ou des explications sur les algorithmes
    Par Marcus2211 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 19/05/2002, 22h18
  4. Recherche de documentation complète en algorithmes
    Par Anonymous dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 29/03/2002, 12h09
  5. Algorithme génétique
    Par Stephane.P_(dis Postef) dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 15/03/2002, 17h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo