Extraire entier d'une chaine [Résolu]

cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 10 nov. 2009 à 18:00 - Dernière réponse : cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention
- 13 nov. 2009 à 17:52
Bonjour, voila j'ai un exo a faire en algo mais je vois pas comment le faire.

la consigne: soit une chaine de caractère. Ecrivez une fonction qui recoit cette chaine et qui extrait toutes les valeures numeriques comprises entre 10 et 30 pour les mettre dans un tableau.
exemple: Ch=<<fsdfs18seryrtr21htrr13rgerger1225rte17htyyt29jy>>
le tableau contiendra : 18,21,13,29

j'ai commencé le début mais je vois pas quelle fonction utilisé et comment savoir une valeure de la chaine des numériques ou non, bref chui perdu , quelqu'un a une idée ? thank you bien d'avance.

#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void main()
{
char ch[200];
printf("saisir une chaine alphanumerique\n");
scanf("%s",&ch);
}

char Extraire_Num(char une_chaine)
{
int i;
int tab[];

for(i=0;i<strlen(une_chaine);i++)
{

Afficher la suite 

Votre réponse

14 réponses

Meilleure réponse
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 12 nov. 2009 à 23:59
3
Merci
Tu n'étais franchement pas loin. Il ne fallait pas de boucle autour de strncpy, puisqu'il copiait déjà tout.
Il te manque quelques truc à reinitialiser, comme chtemp.
On utiliser memset pour affecter une même valeurs à des cases données, et non chtemp = "";

Ca devrait donner ceci (le code n'est pas super propre, il est juste là pour te corriger ton travail actuel, et peut être amélioré):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
** Lira tout jusqu'à atteindre un 0.
** Attention, s'il n'y a pas de 0, il peut y avoir débordement !
*/
void display_tab(int* tab)
{
  while (tab && *tab)
  {
    printf("%i ", *tab);
    ++tab;
  }
  printf("\n");
}

void Extraire_Num(char *une_chaine)
{
  int i = 0;
  int mdeb = 0;
  int mfin = 0;
  int j = 0;
  int tab[256] = {0};
  char chtemp[256] = {0};
  int size = strlen(une_chaine);
  int tmp = 0;

  for (i = 0; i < size; ++i)
  {
    if (isdigit(une_chaine[i]))
    {
      mdeb = i;
      i++;
      printf("indice de debut %d \n",i);
      while (mdeb < size && isdigit(une_chaine[i]))
      {
mfin = i;
i++;
      }
      printf("indice de fin %d\n",i);

      memset(chtemp, 0, 256); /* On met 0 dans toutes les 256 cases */
      strncpy(chtemp, une_chaine + mdeb, mfin - mdeb + 1);
      printf("%s\n", chtemp);

      tmp = atoi(chtemp);
      if (tmp > 10 && tmp < 30)
      {
tab[j] = tmp;
j++;
      }

    }
  }
  display_tab(tab);
}

int main(void)
{
  char ch[256] = "fsdfs18seryrtr21htrr13rgerger1225rte17htyyt29jy";
/*   printf("saisir une chaine alphanumerique\n"); */
/*   scanf("%s",ch); */

  Extraire_Num(ch);

  return 0;
}

Merci cptpingu 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 100 internautes ce mois-ci

Commenter la réponse de cptpingu
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 10 nov. 2009 à 20:51
0
Merci
Je vais te donner tout ce qu'il faut pour résoudre cet exercice:

Tout d'abord la méthode:
- Tu parcours ta chaînes jusqu'à trouver un chiffre.
- Quand tu en trouves un, tu poses un marqueur (c'est à dire tu retiens la position du caractère dans la chaîne).
- Tu continues de parcourir la chaîne, jusqu'à tomber sur un caractère qui n'est pas un chiffre ou la fin de la chaîne. Tu retiens cette position.
- Tu recopie la chaîne de la première position, à la deuxième (du 1er marqueur jusqu'au deuxième).
- Tu convertis la chaîne obtenu en chiffre.
- Si le chiffre est compris entre 10 et 30, tu l'ajoutes au tableau, sinon tu ne fais rien.
- Tu effaces les marqueurs (en leur donnant une position de -1 par exemple).
- Tu repars de la ou tu étais, et tu recommence jusqu'à tomber sur la fin de la chaîne.
- Au sortir de la boucle, tu auras le tableau désiré.

Ensuite, quelques outils:
- Accéder à un élément du tableau: tab[0] => 1er élément, tab[1] => 2ème élément.
- Convertir une chaîne en entier: atoi
- Recopier une chaîne: strcpy, strncpy
- Pour ton tableau, donne lui simplement une grande taille. (Sauf si tu as déjà vu en cours les réallocations mémoires, auquel cas il te faut realloc)

Tu as maintenant tout ce qu'il faut pour résoudre cet exercice.
Commenter la réponse de cptpingu
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 10 nov. 2009 à 21:26
0
Merci
ok merci pour toute les explications jvai tester tous sa demain
Commenter la réponse de cs_Vylco
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 11 nov. 2009 à 16:28
0
Merci
Lut Captain, tu pourrais jeter un oeil à ce que j'ai fais parce que j'ai des erreurs et j'ai des questions aussi
Est ce que sa à l'air correct déja ?
Ensuite chui un peu perdu avec les pointeurs et du coup sa me donne quelque erreur genre

error C2296: '*' : non conforme, l'opérande gauche est du type 'int (__cdecl *)(int)'
error C2296: '*' : non conforme, l'opérande gauche est du type 'size_t (__cdecl *)(const char *)'
error C2297: '*' : non conforme, l'opérande droit est du type 'char *'

Merci d'avance pour les eclaircissements

void Extraire_Num(char *une_chaine)
{
int i,mdeb,mfin,j;
int tab[100];
char chtemp;
j=0;

//parcours de la chaine de caractère
for(i=0;i<strlen(une_chaine);i++)
{
//si on tombe sur un chiffre
if (isdigit*(une_chaine[i]))
{
//on affecte le marqueur de début par l'indice
mdeb=i;

//tant qu'on est pas à la fin de la chaine ou que l'on ne rencontre pas de caractère
while(mdeb<strlen*(une_chaine) && !isdigit*(une_chaine[j]))
{
//le marqueur de fin prend l'indice
mfin=j;
}

//on parcours alors la chaine entre nos 2 marqueurs
for(mdeb<mfin)
{
strcat(chtemp,*une_chaine[i]);
}
//si le chiffre dans la chaine temporaire est >10 et <30
if(atoi(chtemp)>10 && atoi(chtemp)<30)
{
//on copie le nombre dans le tableau
tab[j]=atoi(chtemp);
j++;
chtemp=null;
}
//on affecte le compteur i avec le marqueur de fin  
i=mfin;
}
}
}
Commenter la réponse de cs_Vylco
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 11 nov. 2009 à 16:47
0
Merci
Pourquoi mets tu des étoiles partout ?

"if (isdigit*(une_chaine[i]))" devrait être "if (isdigit(une_chaine[i]))".
De plus : "char chtemp;" est un caractère, donc tu ne peux pas le mettre à "null" (en plus c'est censé être NULL en majuscule).

while(mdeb<strlen*(une_chaine) && !isdigit*(une_chaine[j]))
{
  //le marqueur de fin prend l'indice
  mfin=j;
}

Ici, tu ne dois pas utiliser j, mais i. De plus tu n'incrémentes pas i, donc tu auras une boucle infinie.

//on parcours alors la chaine entre nos 2 marqueurs
for(mdeb<mfin)
{
  strcat(chtemp,*une_chaine[i]);
}

Non, inutile de faire un parcours. Il suffit juste de faire une copie d'une certaine taille, en partant d'un certain indice (via strncpy). Vu que tu n'as pas du voir les pointeurs, on va conserver ta méthode.
Pour que tu puisse faire un strcat, chtemp doit être un chaîne de caractère, et non un caractère.

Pour le reste, ça me semble pas trop mal.
Commenter la réponse de cptpingu
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 11 nov. 2009 à 17:20
0
Merci
J'ai etudieé les pointeurs mais jme perds toujours un peu qd je les utilises , genre quand est ce qu'on doit mettre une * et quand faut pas en mettre, sinon la fonction strncpy m'a l'air plus adaptée mais je vois pas comment l'utilisée ici.

Sinon jai effectué les changements ce qui donne :

void Extraire_Num(char *une_chaine)
{
int i,mdeb,mfin,j;
int tab[100];
char chtemp[100];
j=0;

//parcours de la chaine de caractère
for(i=0;i<strlen(une_chaine);i++)
{
//si on tombe sur un chiffre
if (isdigit(une_chaine[i]))
{
//on affecte le marqueur de début par l'indice
mdeb=i;
i++;


//tant qu'on est pas à la fin de la chaine ou que l'on ne rencontre pas de caractère
while(mdeb<strlen(une_chaine) && !isdigit(une_chaine[i]))
{
//le marqueur de fin prend l'indice
mfin=i;
i++;
}

//on parcours alors la chaine entre nos 2 marqueurs
for(mdeb<mfin)
{
strcat(chtemp,une_chaine[i]);
}
//si le chiffre dans la chaine temporaire est >10 et <30
if(atoi(chtemp)>10 && atoi(chtemp)<30)
{
//on copie le nombre dans le tableau
tab[j]=atoi(chtemp);
j++;
chtemp=NULL;
}
}
}
} 
Commenter la réponse de cs_Vylco
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 12 nov. 2009 à 11:04
0
Merci
J'ai etudieé les pointeurs mais jme perds toujours un peu qd je les utilises , genre quand est ce qu'on doit mettre une * et quand faut pas en mettre, sinon la fonction strncpy m'a l'air plus adaptée mais je vois pas comment l'utilisée ici


Lis ceci:
http://0217021.free.fr/Cours/pointeurs.pdf
(Adaptation en C d'un tuto que j'avais écrit en Delphi pour ce site).

Tu as encore pas mal de petit erreur de type. La fonction strcat est mal utilisé. Je t'invite à lire le pdf, et à essayer d'utiliser strncpy, qui est plus adapté.

for(mdeb<mfin)
{


Tu es sur de ne pas vouloir un while ? Parce qu'un for écrit comme cela, ce n'est pas possible.
Commenter la réponse de cptpingu
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 12 nov. 2009 à 15:13
0
Merci
yo captain, bon j'ai lu ton pdf et j'ai essayé d'améliorer mon code. J'obtiens plus d'erreur à la compilation mais dès que je tape une chaine dans mon scanf j'ai une erreur de type violation d'accés de lecture.

Aussi quand je donne un parametre a ma fonction Extraire_Num(*ch)je dois mettre char devant sinon j'obtiens une erreur:
'Extraire_Num' : identificateur introuvable
Je dois laisser char tu crois ? bref sa me parait bizard.

Sinon j'ai une question bete je fais comment pour afficher mon tableau (tab) une fois la fonction effectuée ?

Merci encore pour ton aide ^^


void main()
{
char *ch;
printf("saisir une chaine alphanumerique\n");
scanf("%s",&ch);

char Extraire_Num(*ch);

}

void Extraire_Num(char *une_chaine)
{
int i,mdeb,mfin,j,k;
int tab[100];
char *chtemp;
chtemp=(char*)malloc(100);
j=0;

//parcours de la chaine de caractère
for(i=0;i<strlen(une_chaine);i++)
{
//si on tombe sur un chiffre
if (isdigit(une_chaine[i]))
{
//on affecte le marqueur de début par l'indice
mdeb=i;
i++;


//tant qu'on est pas à la fin de la chaine ou que l'on ne rencontre pas de caractère
while(mdeb<strlen(une_chaine) && !isdigit(une_chaine[i]))
{
//le marqueur de fin prend l'indice
mfin=i;
i++;
}

//on parcours alors la chaine entre nos 2 marqueurs
while(mdeb<mfin)
{
strncpy(chtemp,&une_chaine[mdeb],100);
mdeb++;
}
//si le chiffre dans la chaine temporaire est >10 et <30
if(atoi(chtemp)>10 && atoi(chtemp)<30)
{
//on copie le nombre dans le tableau
tab[j]=atoi(chtemp);
j++;
chtemp="";
}

}
}
free(chtemp);
}
Commenter la réponse de cs_Vylco
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 12 nov. 2009 à 16:18
0
Merci

char *ch; /* char* ch = malloc(256 * sizeof (char)); */
printf("saisir une chaine alphanumerique\n");
scanf("%s",&ch);
/* free(ch); */

char Extraire_Num(*ch);


Oulah, faut relire le pdf :). Si tu n'alloues pas de mémoire, il ne peut rien mettre dedans.
Ici, inutile d'allouer quoi que ce soit. On va la mettre en dur.

char ch[256];
printf("saisir une chaine alphanumerique\n");
scanf("%s", ch); /* Pas de &, puisque ch n'est pas une variable scalaire (normal), mais un tableau, donc un pointeur */
char Extraire_Num(*ch); /* A effacer, ça n'a rien à faire là ! */


Tu mets ton main, en dessous de la fonction Extraire_Num.
Pour strncpy, il faut faire une soustraction de marqueur, et donc remplacer tes marqueurs de position par des marqueurs d'adresse (quoi qu'on puisse le faire en position).
Commenter la réponse de cptpingu
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 12 nov. 2009 à 18:21
0
Merci
ptain tu gère , sa marche sauf que sa me renvoit un résultat bizard, sa doit venir comme tu dit de strncpy.

tu peux m'expliquer ce que tu veux dire par "Pour strncpy, il faut faire une soustraction de marqueur, et donc remplacer tes marqueurs de position par des marqueurs d'adresse (quoi qu'on puisse le faire en position). " parce que j'ai beau chercher je vois pas comment faire.
Commenter la réponse de cs_Vylco
cptpingu 3826 Messages postés dimanche 12 décembre 2004Date d'inscription 1 octobre 2018 Dernière intervention - 12 nov. 2009 à 18:43
0
Merci
Attention, non testé:

strncpy(chtemp, une_chaine + mdeb, mfin - mdeb);
/* une_chaine + mdeb => On commence à copier la chaine "une_chaine", en partant de "mdeb" caractère */
/* Ex: Si l'adresse de la chaine "une_chaine" est 0x00100, alors "une_chaine + mdeb" donnera "0x00100 + mdeb". */
/* On n'essaie pas d'obtenir le caractère à la position mdeb, mais d'obtenir l'adresse du premier caractère (pas sa valeur, mais ou il est placé en mémoire). Ce qui équivaut à donné l'endroit ou commence la sous-chaine en mémoire */

/* mfin - mdeb => taille du morceau de la chaine à récupérer, logique, non :p ? */
/* Ex: Si le premier caractère d'une chaine est à l'adresse 0x00100 et le dernier (caractère terminal '\0') à l'adresse 0x00108, alors la chaîne fera 8 caractères sans compter le caractère terminal '\0' (0x00108 - 0x00100 = 8) */


Ca devrait le faire, mais encore une fois je n'ai pas testé.
Commenter la réponse de cptpingu
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 12 nov. 2009 à 20:52
0
Merci
ok donc sa me donne :

while(mdeb<mfin)
{
strncpy(chtemp, une_chaine + mdeb, mfin - mdeb);
mdeb++;
}


Ta methode me donne pas d'erreur a la compilation mais j'ai toujours le meme resultat quand je fais un printf de mon tableau tab :1244084, sa doit etre lié au fait que le printf de chtemp a la fin du while me donne un truc du genre 1=================================²²²²
Autrement un printf de mdeb et mfin me donne les bons indices par contre (ya au moins un truc qui marche ).

jte redonne mon code en entier au cas ou j'aurai foiré qque part :

void Extraire_Num(char *une_chaine)
{
int i,mdeb,mfin,j,k;
int tab[100];
char *chtemp;
chtemp=(char*)malloc(100);
j=mdeb=mfin=0;

//parcours de la chaine de caractère
for(i=0;i<strlen(une_chaine);i++)
{
//si on tombe sur un chiffre
if (isdigit(une_chaine[i])!=0)
{
//on affecte le marqueur de début par l'indice
mdeb=i;
i++;
printf("indice de debut %d \n",i);


//tant qu'on est pas à la fin de la chaine ou que l'on ne rencontre pas de caractère
while(mdeb<strlen(une_chaine) && isdigit(une_chaine[i])!=0)
{
//le marqueur de fin prend l'indice
mfin=i;
i++;
}
printf("indice de fin %d\n",i);

//on parcours alors la chaine entre nos 2 marqueurs
while(mdeb<mfin)
{
strncpy(chtemp, une_chaine + mdeb, mfin - mdeb);
mdeb++;
}
printf("%s\n",chtemp);
//si le chiffre dans la chaine temporaire est >10 et <30
if(atoi(chtemp)>10 && atoi(chtemp)<30)
{
//on copie le nombre dans le tableau
tab[j]=atoi(chtemp);
j++;
chtemp="";
}

}
}
free(chtemp);
printf("%d",tab);
getch();
}

void main()
{
char ch[256];

printf("saisir une chaine alphanumerique\n");
scanf("%s",ch);

Extraire_Num(ch);

}	
Commenter la réponse de cs_Vylco
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 12 nov. 2009 à 21:04
0
Merci
ptete en servant un bon wisky jvai avoir une illumination, qu'en pense tu ?
Commenter la réponse de cs_Vylco
cs_Vylco 14 Messages postés jeudi 20 septembre 2007Date d'inscription 26 novembre 2009 Dernière intervention - 13 nov. 2009 à 17:52
0
Merci
yo captain, sa marche nikel j'ai remis tout en ordre et remis des commentaires maintenant c'est propre . Encore merci pour ton aide et passe un bon week end
Commenter la réponse de cs_Vylco

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.