En utilisant le code suivant:
char *name = malloc(sizeof(char) + 256);
printf("What is your name? ");
scanf("%s", name);
printf("Hello %s. Nice to meet you.\n", name);
Un utilisateur peut entrer son nom, mais quand il entre un nom avec un espace comme Lucas Aardvark
, scanf()
coupe tout après Lucas
. Comment faire scanf()
permettre des espaces
Les personnes (et surtout les débutants) ne doivent jamais utiliser scanf("%s")
ou gets()
ni aucune autre fonction ne bénéficiant pas d'une protection contre le débordement de mémoire tampon, sauf si vous êtes certain que l'entrée aura toujours un format spécifique (et peut-être même pas à ce moment-là) .
Rappelez-vous que scanf
signifie "numériser formaté" et qu'il existe un précieux petit moins formaté que les données saisies par l'utilisateur. C'est idéal si vous avez un contrôle total sur le format des données d'entrée, mais que vous ne pouvez généralement pas l'utiliser pour la saisie par l'utilisateur.
Utilisez fgets()
(qui a la protection de débordement de tampon) pour obtenir votre entrée dans une chaîne et sscanf()
pour l’évaluer. Puisque vous voulez juste ce que l'utilisateur a entré sans analyser, vous n'avez pas vraiment besoin de sscanf()
dans ce cas:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Maximum name size + 1. */
#define MAX_NAME_SZ 256
int main(int argC, char *argV[]) {
/* Allocate memory and check if okay. */
char *name = malloc(MAX_NAME_SZ);
if (name == NULL) {
printf("No memory\n");
return 1;
}
/* Ask user for name. */
printf("What is your name? ");
/* Get the name, with size limit. */
fgets(name, MAX_NAME_SZ, stdin);
/* Remove trailing newline, if there. */
if ((strlen(name) > 0) && (name[strlen (name) - 1] == '\n'))
name[strlen (name) - 1] = '\0';
/* Say hello. */
printf("Hello %s. Nice to meet you.\n", name);
/* Free memory and exit. */
free (name);
return 0;
}
Essayer
char str[11];
scanf("%10[0-9a-zA-Z ]", str);
J'espère que cela pourra aider.
Cet exemple utilise un scanset inversé, donc scanf continue à prendre des valeurs jusqu'à ce qu'il rencontre un '\ n' - nouvelle ligne, ainsi les espaces sont également sauvegardés.
#include <stdio.h>
int main (int argc, char const *argv[])
{
char name[20];
scanf("%[^\n]s",name);
printf("%s\n", name);
return 0;
}
Vous pouvez utiliser ceci
char name[20];
scanf("%20[^\n]", name);
Ou ca
void getText(char *message, char *variable, int size){
printf("\n %s: ", message);
fgets(variable, sizeof(char) * size, stdin);
sscanf(variable, "%[^\n]", variable);
}
char name[20];
getText("Your name", name, 20);
N'utilisez pas scanf()
pour lire des chaînes sans spécifier une largeur de champ. Vous devriez également vérifier les valeurs de retour pour les erreurs:
#include <stdio.h>
#define NAME_MAX 80
#define NAME_MAX_S "80"
int main(void)
{
static char name[NAME_MAX + 1]; // + 1 because of null
if(scanf("%" NAME_MAX_S "[^\n]", name) != 1)
{
fputs("io error or premature end of line\n", stderr);
return 1;
}
printf("Hello %s. Nice to meet you.\n", name);
}
Sinon, utilisez fgets()
:
#include <stdio.h>
#define NAME_MAX 80
int main(void)
{
static char name[NAME_MAX + 2]; // + 2 because of newline and null
if(!fgets(name, sizeof(name), stdin))
{
fputs("io error\n", stderr);
return 1;
}
// don't print newline
printf("Hello %.*s. Nice to meet you.\n", strlen(name) - 1, name);
}
Vous pouvez utiliser la fonction fgets()
pour lire une chaîne ou utiliser scanf("%[^\n]s",name);
pour que la lecture de chaîne se termine lorsque vous rencontrez un caractère de nouvelle ligne.
Maintenant, une partie de POSIX, néanmoins.
Il s’occupe également du problème d’allocation de mémoire tampon que vous avez évoqué précédemment, bien que vous deviez vous occuper de free
ing de la mémoire.
Si quelqu'un cherche encore, voici ce qui a fonctionné pour moi: lire une longueur arbitraire de chaîne, y compris des espaces.
Merci à de nombreuses affiches sur le Web pour avoir partagé cette solution simple et élégante. Si cela fonctionne, le crédit leur revient, mais toute erreur est la mienne.
char *name;
scanf ("%m[^\n]s",&name);
printf ("%s\n",name);
Vous pouvez utiliser scanf
à cette fin avec un petit truc. En fait, vous devez autoriser les entrées utilisateur jusqu'à ce que l'utilisateur appuie sur Entrée (\n
). Cela tiendra compte de tous les personnages, y compris space. Voici un exemple:
int main()
{
char string[100], c;
int i;
printf("Enter the string: ");
scanf("%s", string);
i = strlen(string); // length of user input till first space
do
{
scanf("%c", &c);
string[i++] = c; // reading characters after first space (including it)
} while (c != '\n'); // until user hits Enter
string[i - 1] = 0; // string terminating
return 0;
}
Comment ça marche? Lorsque l'utilisateur saisit des caractères à partir de l'entrée standard, ils sont stockés dans chaîne variable jusqu'au premier espace vide. Après cela, le reste de l'entrée restera dans le flux d'entrée et attendra le prochain scanf. Ensuite, nous avons une boucle for
qui prend char par char à partir du flux d’entrée (jusqu'au \n
) et les ajoute à la fin de chaîne variable, formant ainsi une chaîne complète identique à celle saisie par le clavier.
J'espère que cela aidera quelqu'un!
Bien que vous ne devriez vraiment pas utiliser scanf()
pour ce genre de chose, car il existe de bien meilleurs appels tels que gets()
ou getline()
, vous pouvez le faire:
#include <stdio.h>
char* scan_line(char* buffer, int buffer_size);
char* scan_line(char* buffer, int buffer_size) {
char* p = buffer;
int count = 0;
do {
char c;
scanf("%c", &c); // scan a single character
// break on end of line, string terminating NUL, or end of file
if (c == '\r' || c == '\n' || c == 0 || c == EOF) {
*p = 0;
break;
}
*p++ = c; // add the valid character into the buffer
} while (count < buffer_size - 1); // don't overrun the buffer
// ensure the string is null terminated
buffer[buffer_size - 1] = 0;
return buffer;
}
#define MAX_SCAN_LENGTH 1024
int main()
{
char s[MAX_SCAN_LENGTH];
printf("Enter a string: ");
scan_line(s, MAX_SCAN_LENGTH);
printf("got: \"%s\"\n\n", s);
return 0;
}
/*reading string which contains spaces*/
#include<stdio.h>
int main()
{
char *c,*p;
scanf("%[^\n]s",c);
p=c; /*since after reading then pointer points to another
location iam using a second pointer to store the base
address*/
printf("%s",p);
return 0;
}