Recuperer une chaine avec scanf

Résolu/Fermé
Benjamin - 9 janv. 2011 à 14:25
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 10 janv. 2011 à 20:37
Bonjour,

Je dois recuperer une suite de chaines avec scanf (je ne peux pas utiliser getchar).
Seulement j aimerais que la saisie s arrete une fois que l utilisateur ne rentre plus rien (Et oui tout simplement =)
Seulement je n arrive pas a indiquer les bonnes conditions dans ma boucle.
j ai essayer while (chaine != EOF) mais sans resultat.

Quelqu un pourrait il m aider ?

merci a tous

15 réponses

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 9/01/2011 à 17:08
Voici une solution, il faudra bien sûr remplacer les printf par ce que tu veux...

#include "stdio.h" 
#include "stdlib.h" 

int main(void) 
{
	char texte[BUFSIZ];
	char c;
	int i;

	while (1)
	{
		for (i=0, c=' '; c!='\n' && i<BUFSIZ-1; i++)
		{
			scanf("%c",&c);
			texte[i]=c;
		}
		texte[i-1]='\0';

		if (texte[0]=='\0')
		{
			break;
		}
		else
		{
			printf("ECHO -> %s\n",texte);
		}
	}

	printf("STOP");
	return 0; 
}

La confiance n'exclut pas le contrôle
2
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
9 janv. 2011 à 15:57
Pourquoi tu ne peux pas utiliser getch() ?
C'est pourtant la meilleure solution !

Si tu ne peux vraiment pas utiliser getch(), et que tu es obligé d'utiliser scanf(), alors c'est tout simplement impossible.

Si tu peux utiliser une autre fonction (autre que scanf et getch), il y a un moyen pour récupérer des chaînes entières, avec des espaces. Et dans ce cas-là, les chaînes vides sont autorisées, et tu pourras effectuer cela.

Attend, je cherche un peu cette fonction, fais-le aussi de ton côté, ce sont des mots-clés du genre "get line", "cin line", "scanf avec espace", etc;
1
VieTgOOx Messages postés 160 Date d'inscription dimanche 4 janvier 2009 Statut Membre Dernière intervention 9 janvier 2011 26
9 janv. 2011 à 16:02
Salut!

Ben écoute, tu fais une condition si la chaine que l'utilisateur à rentré est vide tu sort et tu continues l'exécution de ton programme, point barre. Genre while (chaine != NULL)... Je vois pas trop ou est le problème?
Sinon, tu lui demande avant qu'il ne commence la saisie combien de valeur il va rentrer, comme sa tu fais une boucle en fonction du nombre de valeur qu'il t'as indiqué qu'il veux rentrer genre while(i=0; i<nbVal-1; i++).

Amicalement,
VieTgOOx.
1
Je ne peux pas utilise getchar puisque cest une condition de l enonce.
Cest d ailleurs bien dommage =)

Je te rappelle que l utilisateur appuie sur entree apres chaque nom rentre.
Il ne s agit pas vraiment d espaces, si ?
1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
Modifié par Bilow le 9/01/2011 à 16:07
Voilà, j'ai trouvé ! C'était un de mes premiers posts :
https://forums.commentcamarche.net/forum/affich-15369031-c-ecrire-string-dans-fichier

Lis un peu, la moitié du post parle de la conversion de string en chaîne.
En utilisant string phrase; getline(cin, phrase); tu^pourras récupérer des chaînes vides.

Je cherche encore un peu le code complet, et je te le passe.
Le lien le plus utile est :
http://www.cplusplus.com/reference/string/string/c_str/

Tu me demandes pourquoi on parle d'espaces ? C'est simple :
Scanf() est incapable de recevoir des chaînes vides. Puisque je sais qu'il existe une autre fonction qui en est capable, je te la donne (getline). Mais celle-ci n'accepte que les strings... ALors, on cherche à convertir le string (vide ou non) en chaîne (vide ou non) afin de comparer.

;)
1
Je vais regarder ca de suite.

Un grand merci
1
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
9 janv. 2011 à 15:34
Qu'est-ce que tu entends par "l'utilisateur ne rentre plus rien" ?
Si ça veut dire que l'utilisateur n'a rien entré depuis 10 secondes (par exemple), il faut donc que tu utilises une gestion du temps (avec le signal SIGALRM par exemple)
0
Excuse moi,je me suis mal exprime.

l utilisateur doit rentre une suite de chaine, qui sont en fait des noms.
Il rentre par exemple DELL, il appuie sur entree. puis APPLE etc..
Je voudrais arreter la saisie lorsque l utilisateur n appuie que sur entree, ce qui signifierait "je n ai plus de noms a mettre".

Mon soucis est que la saisie ne s arrete jamais.


Merci beaucoup pour ta reponse
0
toute ces fonctions sont utilisables en C ?
0
Vietgoox cest exactement ma question seulement j ai essayer while (chaine != EOF) mais sans resultat...
0
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
9 janv. 2011 à 16:11
Je suis en train d'écrire le code qui permettra de faire ce que tu veux. Après, je regarderai la compatibilité. Mais il faudra inlure iostream, même si c'est un projet C...
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
9 janv. 2011 à 16:12
iostream ne marchera pas en C pur.
il faudra inclure stdio.h et surement stdlib.h aussi
0
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
9 janv. 2011 à 16:14
Tant que le code fonctionne, qu'importe le nombre de bibliothèques. Je regardrai la compatibilité à la fin.
Benjamin, attend encore 5 minutes :D
0
Aucun probleme vraiment , merci beaucoup de t en occuper
0
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
9 janv. 2011 à 16:26
Voila !

Il y a juste un problème :
Cela dépend de ton IDE. J'ai essayé de compiler en C avec Dev-Cpp, il m'a dit qu'il ne trouvait pas cette librairie. Essaye avec ton IDE. En attendant je cherche (encore) une solution.

Petite chose à noter : j'ai utilisé sprintf(); Certains râleront que je l'aie utilisé, mais alors qu'ils m'expliquent parce que je n'ai jamais trouvé pourquoi c'était déconseillé. Tant que ca fonctionne.

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int main(){
  char *cstr, *p;
  string phrase; // C'est ta phrase ! Vide ou non
  char chaine_entree [30] = ""; // Ce sera ta chaîne
  int already_started = 0; // Sert à savoir si on doit insérer un espace ou non (pas important pour toi)
  printf("Entrez une phrase, avec espaces ou non, vide ou pas : ");
  getline(cin, phrase); // On demande à l'utilisateur d'entrer quelque chose ou rien
  
  // Conversion de string en chaîne
  cstr = new char [phrase.size()+1];
  strcpy(cstr, phrase.c_str());
  p=strtok(cstr," ");
  while(p!=NULL){
  if(already_started){
  sprintf(chaine_entree, "%s %s", chaine_entree, p);
  }
  else{
  sprintf(chaine_entree, "%s", p);
  }
  p=strtok(NULL," ");
  already_started = 1;
  }
  delete[] cstr;
  // Fin de traitement
  
  printf("\nLa chaine finale est : %s\n\n", chaine_entree);
  if(strcmp(chaine_entree, "")){ // La chaîne n'est pas vide
  printf("La chaine n'est pas vide !\n\n");
  }
  else{
  printf("La chaine est vide !\n\n");
  }
  
  system("pause");
  return 0;
} 


Dis-moi quoi :)
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 9/01/2011 à 16:33
getline et cin (qui appartient à iostream) ne peuvent pas être utilisés en C, c'est du C++ !
De même que using namespace std, <string>, <cstring>, et l'opérateur new (j'en oublie surement)
0
Oui malheureusement ca ne marche pas en C ..
J ai en fait juste besoin d un moyen de sortir de la saisie ..
j ai deja essayer while (chaine != EOF) ou while (chaine != NULL)
Et ton idee est bonne mais en C je m en sors pas..
0
Bilow Messages postés 1022 Date d'inscription samedi 21 août 2010 Statut Membre Dernière intervention 2 août 2015 117
9 janv. 2011 à 16:38
scanf() ne reçois pas de chaîne vide. Je ne pense vraiment pas qu'il y ait un autre moyen de résoudre ce problème, excepté de demander à l'utilisateur d'entrer un espace au lieu de rien, ou bien de compiler en C++ ; Désolé
0
VieTgOOx Messages postés 160 Date d'inscription dimanche 4 janvier 2009 Statut Membre Dernière intervention 9 janvier 2011 26
9 janv. 2011 à 16:42
Voilà pourquoi j'aime pas le C. Génial pour la gestion de la mémoire, mais tellement prise de tête...développe en JAVA ^^ c'est le jour et la nuit =) !
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 9/01/2011 à 17:19
Bonjour,

Lorsque l'utilisateur appuie sur la touche entrée cela est converti en \n. Pourquoi ne pas utiliser cette condition là ?
En gros, tu arrêtes la boucle dès que la chaîne est égale à "\n" ou si le premier caractère est '\n' ?

Google is your friend
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 9/01/2011 à 17:27
Le problème vient du fait que la lecture d'une chaîne vide (on ne fait que rentrer "\n") ne termine pas l'instruction scanf qui continue jusqu'à ce qu'on lui donne au moins un caractère imprimable puis \n
Par exemple, il n'est pas possible d'obtenir str="\t" avec un scanf("%s",&str);
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 janv. 2011 à 17:30
@KX,
Par exemple, il n'est pas possible d'obtenir s="\t\n" avec un scanf("%s",...);
Ca tombe bien, je ne parlais pas de "%s". scanf ne se résume pas à ça.
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
9 janv. 2011 à 17:32
Non je sais, dans le code que j'ai proposé, j'ai utilisé %c pour contourner le problème...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 janv. 2011 à 17:39
Certes, mais bon ça fait un peu bricole avec le %c.
Moi je verrai plutôt un truc du genre :
#include <stdio.h>

int main(void){
	int i=0,j;
	char texte[10][10];
	
	while(scanf("%[^\n]",texte[i])==1) {
		scanf("%*c");
		i++;
	}	
	scanf("%*c");
	
	for(j=0;j<i;j++)
		printf("texte[%d]=%s\n",j,texte[j]);

	return 0;
}


Bien sûr, c'est à améliorer.

Cdlt,
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
9 janv. 2011 à 23:49
Je comprends le scanf("%[^\n]") mais pas le scanf("%*c"); quésaco ?
0
Ca fonctionne, le changement en %c est tres joli !
Merci a tous pour tous ces efforts !
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 janv. 2011 à 22:13
Tu parles de quel code ?
Celui posté avec le while(1) ou celui avec le while(scanf(...)) ?
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
9 janv. 2011 à 23:48
À la limite peu importe si son problème est résolu...
Il a deux solutions qui marchent, bien que je trouve la tienne nettement plus propre ;-)
0