fflush(stdin)
?stdin
?printf()
ne s'affiche pas ?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();
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;
double result = strtod(test, &err);
if (err != NULL) {
if (err == test) {
/* conversion impossible */
}
else {
/* erreur de conversion */
}
}
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, cette fonction modifie son premier paramètre. Elle utilise une variable globale cachée, elle est donc à utiliser avec précautions.
Dans des cas simples, on pourra utiliser la fonction
strchr()
.
fflush(stdin)
?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
?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.
printf()
ne s'affiche pas ?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 :
fflush()
(cf. 14.4)
'\n'
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;
}
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).
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
.
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.
if (fopen("fichier.txt", "r") == NULL) {
fputs("Le fichier n'existe pas,"
" ou vous n'avez pas les droits necessaires\n", stderr);
}
Dans la norme POSIX, il existe la fonction
access()
, mais certains systèmes n'implémentent pas
cette interface.
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
).
"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"
.
sleep()
en
POSIX, elle provoque une attente passive pour une
durée donnée en secondes.
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);
.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 lier le programme avec la bibliothèque adéquate :
gcc -lm monfic.o -o monprog
faq-fclc 5/3/2002 (8h 59:05)