fflush(stdin)
?stdin
?Il suffit d'utiliser sprintf().
char sz[4]; sprintf(sz, "%d", 123);
Pour convertir un double
ou un long
,
il faut utiliser %f
ou %ld
.
Le problème de sprintf() est qu'il faut réserver assez de place pour la chaîne résultat. Ainsi le code
char sz[6]; sprintf(sz, "%u", i);
marchera sur des machines où i
est un entier 16 bits,
mais il plantera si i
est un entier plus grand (>
99999).
En C99, la fonction snprintf permet d'éviter les débordements :
char sz[4]; n = snprintf(sz, sizeof sz, "%d", 123); if (n < 0 || n >= sizeof sz) erreur();
Si le nombre espéré est un entier, il faut utiliser la fonction strtol(). Elle convertit une chaîne en un entier long, dans une base donnée.
Si le nombre est un réel (float
ou double
),
alors la fonction strtod() fera très bien l'affaire.
char test[] = " -123.45e+2"; char * err = NULL; errno = 0; double result = strtod(test, &err); if (err == test) { printf("Erreur de conversion :\n"); } else { if (errno == ERANGE) { printf("Depassement :\n"); } else { printf("Conversion reussie :\n"); if (*err == '\0') { printf("Pour toute la chaine\n"); } } }
Si le nombre est un long double
(C99 seulement) alors la
fonction strtold() est à préférer.
La fonction strtok() est faite pour ça !
char sz1[] = "this is,an example ; "; char sz2[] = ",; "; char *p; p = strtok(sz1, sz2); if (p != NULL) { puts(p); while ((p = strtok(NULL, sz2)) != NULL) { puts(p); } }
Attention, la fonction strtok() souffre au moins des problèmes / caractéristiques suivants :
Dans des cas simples, on pourra utiliser la fonction strchr().
fflush(stdin)
?La fonction fflush() a un comportement défini
uniquement sur les flux ouverts en écriture tels que
stdout
. Il est possible que sur votre système, appliquer
cette fonction à stdin
soit possible, mais c'est alors
une extension non standard. Le comportement est indéterminé, et
imprévisible.
Il faut bien comprendre que stdin
n'est pas forcément
relié au clavier, mais peut être rattaché à un réseau, un fichier, etc.
stdin
?Une bonne manière est de lire sur le flux tant qu'il n'est pas vide, avec les fonctions habituelles comme fgets() ou getchar(). Voici un exemple avec cette dernière :
c = getchar(); if (c != '\n') while ((getchar()) != '\n') { };
Ce morceau de code permet de lire un caractère, et vide ce qui
peut rester dans le buffer, notamment le '\n'
final.
Le flux standard stdout
, sur lequel écrit
printf() est bufferisé. C'est à dire que les caractères
sont écrits dans un tampon (une zone mémoire). Lorque celui-ci est
plein, ou lorsqu'une demande explicite est faite, il est vidé dans
le flux proprement dit (sur l'écran généralement).
Tant que le buffer n'est pas vidé, rien ne s'affiche.
Pour vider le buffer, il y a trois possibilités :
'\n'
Il faut simplement utiliser les fonctions time(), ctime() et/ou localtime(), qui contrairement à leurs noms donnent l'heure et la date.
Voici un petit exemple :
#include <stdio.h> #include <time.h> int main(void) { time_t now; time(&now); printf("Il est %.24s.\n", ctime(&now)); return 0; }
Il faut simplement utiliser la fonction difftime().
Cette fonction prend deux time_t
en paramètres et renvoie
un double
.
Ce n'est pas possible. La bibliothèque standard inclut un générateur pseudo-aléatoire, la fonction rand(). Toutefois, l'implémentation dépend du système, et celle-ci n'est généralement pas très bonne (en terme de résultats statistiques). Si rand() ne vous suffit pas (simulation numérique ou cryptologie), il vous faudra regarder du coté de bibliothèques mathématiques, dont de nombreuses se trouvent sur Internet. En particulier, on consultera les paragraphes 7-0 et 7-1 des Numerical Recipes in C (cf. 4.5) et le volume 2 de TAoCP (cf. 3.9).
La méthode la plus simple à faire,
rand() % N
qui renvoie un nombre entre 0
et N-1
est aussi
la moins bonne.
En effet, les bits de poids faibles ont une distribution très peu
aléatoire. Par exemple, le bit de poids le plus faible a une
distribution qui peut être celle-ci sur un mauvais générateur :
0 1 0 1 0 1 0 1 0 1 ...
Voici la méthode préconisée dans Numerical Recipes (cf.4.5) :
(int)((double)rand() / ((double)RAND_MAX + 1) * N)
RAND_MAX
est défini dans stdlib.h
,
et N
doit être plus petit que RAND_MAX
.
C'est normal, et c'est fait exprès. Pour contrer cela, il faut utiliser une graine pour le générateur qui change à chaque lancement du programme. C'est la fonction srand() qui s'en charge.
On peut utiliser l'heure système, avec time(), de la facon suivante :
srand(time(NULL));
Notez qu'il est peu utile d'appeler la fonction srand() plus d'une fois par programme.
En C ISO, le seul moyen de savoir si un fichier existe, c'est d'essayer de l'ouvrir.
{ FILE *fp = fopen ("fichier.txt", "r"); if (fp == NULL) { fputs("Le fichier n'existe pas,\n" "ou vous n'avez pas les droits necessaires\n" "ou il est inaccessible en ce moment\n" , stderr); } else { /* ... operation sur le fichier */ fclose(fp); } }
Dans la norme POSIX, il existe la fonction access(), mais certains systèmes n'implémentent pas cette interface.
Malheureusement, les fonctions stat() et
fstat() de la norme POSIX ne sont pas
reprises dans la norme ISO.
La seule solution standard est d'utiliser fseek() et
ftell().
Toutefois, cela ne marche pas pour les très gros fichiers
(supérieurs à LONG_MAX
).
Il faut ouvrir le fichier en mode « binaire », en passant la chaîne
"rb"
en mode d'ouverture à la fonction fopen().
Cela évite les transformations inopportunes et les problèmes des
caractères de contrôle.
De même, pour écrire dans un fichier binaire, on utilise le mode
"wb"
.
Il n'y a pas de fonction standard pour cela. Il existe toutefois la fonction sleep() en POSIX, elle provoque une attente passive pour une durée donnée en secondes.
La fonction qsort() est une bonne fonction de tri, qui implémente le Quick Sort. Le plus simple est de donner un exemple :
/* Fonction qui compare deux pointeurs vers des chaines pour qsort */ int pstrcmp(const void * p1, const void * p2) { return strcmp(*(char * const *)p1, *(char * const *)p2); }
Les paramètres doivent être des pointeurs génériques pour
qsort().
p1
et p2
sont des pointeurs sur des chaînes.
Un tableau de chaînes doit être pris au sens d'un tableau de
pointeurs vers des char *
.
L'appel à qsort() ressemble alors à :
qsort(tab, sizeof tab, sizeof *tab, pstrcmp);
Les en-têtes (les .h
) ne contiennent que les
prototypes des fonctions.
Le code proprement-dit de ces fonctions se trouve dans des
fichiers objets. Ce code doit être « lié » au tien. Cela est fait
par un éditeur de liens.
Pour certaines fonctions, il faut spécifier explicitement à l'éditeur de liens où il peut les trouver (et ce particulièrement pour les fonctions non-standard).
Par exemple, sous Unix, pour utiliser les fonctions mathématiques, il faut généralement lier le programme avec la bibliothèque adéquate :
cc -lm monfic.o -o monprog