les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string=
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string=
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string=
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
kanze wrote on 22/06/2006 11:17:
La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose d'imprévu.
On peut bien le « corriger » pour qu'il marche, tout en
gardant le char[], mais à coût de pas mal de complications en
plus. Or qu'avec std::string, il marche comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en effet.
kanze wrote on 22/06/2006 11:17:
La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose d'imprévu.
On peut bien le « corriger » pour qu'il marche, tout en
gardant le char[], mais à coût de pas mal de complications en
plus. Or qu'avec std::string, il marche comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en effet.
kanze wrote on 22/06/2006 11:17:
La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose d'imprévu.
On peut bien le « corriger » pour qu'il marche, tout en
gardant le char[], mais à coût de pas mal de complications en
plus. Or qu'avec std::string, il marche comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en effet.
kanze wrote on 22/06/2006 11:17:La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose
d'imprévu. On peut bien le « corriger » pour qu'il marche,
tout en gardant le char[], mais à coût de pas mal de
complications en plus. Or qu'avec std::string, il marche
comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en
effet.
note que je n'avais pas indiqué que string n'était pas un bon
choix, même si je sais, ne pas avoir vanter la STL est déjà
une faute coupable
En fait, le seul cas que je peux imaginer où la solution
avec char[] a un avantage ici, c'est si on est payé à la
ligne.
comment leur dire qu'il est des monde utilisant le langage C++
qui ne disposent pas d'un runtime illimité et pas de
sacro-sainte STL ??....
J'avoue ne pas comprendre ces histoires de « balancée » et
d'autres. C'est peut-être une /préjudice/ personnelle, mais
je "préférence" ? trouve qu'une solution simple et correcte
soit plus pertinante à une solution complexée et erronée.
Quant à la performance : sur ma machine, les opérations sur
std::string sont toujours bien plus rapide que le temps
qu'il me faut pour tapper le texte en entrée. Au point
où on pourrait carrément ignorer leur temps d'exécution.
hein ?!? quel rapport avec les perf de saisies ? (de qui tape
vite sans regarder?)
kanze wrote on 22/06/2006 11:17:
La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose
d'imprévu. On peut bien le « corriger » pour qu'il marche,
tout en gardant le char[], mais à coût de pas mal de
complications en plus. Or qu'avec std::string, il marche
comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en
effet.
note que je n'avais pas indiqué que string n'était pas un bon
choix, même si je sais, ne pas avoir vanter la STL est déjà
une faute coupable
En fait, le seul cas que je peux imaginer où la solution
avec char[] a un avantage ici, c'est si on est payé à la
ligne.
comment leur dire qu'il est des monde utilisant le langage C++
qui ne disposent pas d'un runtime illimité et pas de
sacro-sainte STL ??....
J'avoue ne pas comprendre ces histoires de « balancée » et
d'autres. C'est peut-être une /préjudice/ personnelle, mais
je "préférence" ? trouve qu'une solution simple et correcte
soit plus pertinante à une solution complexée et erronée.
Quant à la performance : sur ma machine, les opérations sur
std::string sont toujours bien plus rapide que le temps
qu'il me faut pour tapper le texte en entrée. Au point
où on pourrait carrément ignorer leur temps d'exécution.
hein ?!? quel rapport avec les perf de saisies ? (de qui tape
vite sans regarder?)
kanze wrote on 22/06/2006 11:17:La question est plutôt : en quoi un code simple et correct
serait un plus ici ? Le code initialement posté plante
carrément dès que l'utilisateur entre quelque chose
d'imprévu. On peut bien le « corriger » pour qu'il marche,
tout en gardant le char[], mais à coût de pas mal de
complications en plus. Or qu'avec std::string, il marche
comme il faut d'office.
évaluons les "pas mal de complication":
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
5 lignes de code et une déclaration, grosse complication en
effet.
note que je n'avais pas indiqué que string n'était pas un bon
choix, même si je sais, ne pas avoir vanter la STL est déjà
une faute coupable
En fait, le seul cas que je peux imaginer où la solution
avec char[] a un avantage ici, c'est si on est payé à la
ligne.
comment leur dire qu'il est des monde utilisant le langage C++
qui ne disposent pas d'un runtime illimité et pas de
sacro-sainte STL ??....
J'avoue ne pas comprendre ces histoires de « balancée » et
d'autres. C'est peut-être une /préjudice/ personnelle, mais
je "préférence" ? trouve qu'une solution simple et correcte
soit plus pertinante à une solution complexée et erronée.
Quant à la performance : sur ma machine, les opérations sur
std::string sont toujours bien plus rapide que le temps
qu'il me faut pour tapper le texte en entrée. Au point
où on pourrait carrément ignorer leur temps d'exécution.
hein ?!? quel rapport avec les perf de saisies ? (de qui tape
vite sans regarder?)
Sylvain writes:
| Gabriel Dos Reis wrote on 22/06/2006 05:48:
| > Sylvain writes:
| > | Gabriel Dos Reis wrote on 22/06/2006 05:13:
| > | > et quel est le rapport avec l'âge du capitaine ?
| > | et aussi qu'à la question: "Comment je peux faire
| > | pour que le programme teste un à un les caratères?"
| > | | une réponse, un peu plus sécuritaire, est:
| > | | const size_t PASS_LENGTH = ?; // could be a hash block size
| > | | bool state = true;
| > | for (register int i = 0; i < PASS_LENGTH; ++i)
| > | state &= (candidate[i] == reference[i]);
| > | | au moins ici le temps ne varira pas avec la saisie.
| > Parce que ?
| parce que PASS_LENGTH est une constante ...
Et alors, le mot de passe de reference a aussi une longeur
constante. Explication à revoir.
Sylvain <noSpam@mail.net> writes:
| Gabriel Dos Reis wrote on 22/06/2006 05:48:
| > Sylvain <noSpam@mail.net> writes:
| > | Gabriel Dos Reis wrote on 22/06/2006 05:13:
| > | > et quel est le rapport avec l'âge du capitaine ?
| > | et aussi qu'à la question: "Comment je peux faire
| > | pour que le programme teste un à un les caratères?"
| > | | une réponse, un peu plus sécuritaire, est:
| > | | const size_t PASS_LENGTH = ?; // could be a hash block size
| > | | bool state = true;
| > | for (register int i = 0; i < PASS_LENGTH; ++i)
| > | state &= (candidate[i] == reference[i]);
| > | | au moins ici le temps ne varira pas avec la saisie.
| > Parce que ?
| parce que PASS_LENGTH est une constante ...
Et alors, le mot de passe de reference a aussi une longeur
constante. Explication à revoir.
Sylvain writes:
| Gabriel Dos Reis wrote on 22/06/2006 05:48:
| > Sylvain writes:
| > | Gabriel Dos Reis wrote on 22/06/2006 05:13:
| > | > et quel est le rapport avec l'âge du capitaine ?
| > | et aussi qu'à la question: "Comment je peux faire
| > | pour que le programme teste un à un les caratères?"
| > | | une réponse, un peu plus sécuritaire, est:
| > | | const size_t PASS_LENGTH = ?; // could be a hash block size
| > | | bool state = true;
| > | for (register int i = 0; i < PASS_LENGTH; ++i)
| > | state &= (candidate[i] == reference[i]);
| > | | au moins ici le temps ne varira pas avec la saisie.
| > Parce que ?
| parce que PASS_LENGTH est une constante ...
Et alors, le mot de passe de reference a aussi une longeur
constante. Explication à revoir.
Arnaud Meurgues writes:Question : l'introduction de nop aléatoires ne
pourraient-ils pas être plus simple tout en étant suffisante
pour empêcher de déduire quoique ce soit du temps d'analyse
?
De l'aleatoire asser sur pour ce genre d'application c'est
difficile a faire d'une part, d'autre part ca ne fait
qu'ajouter du bruit qu'on peut filtrer au prix d'un facteur
constant.
Arnaud Meurgues <news.arnaud@meurgues.non.fr.invalid> writes:
Question : l'introduction de nop aléatoires ne
pourraient-ils pas être plus simple tout en étant suffisante
pour empêcher de déduire quoique ce soit du temps d'analyse
?
De l'aleatoire asser sur pour ce genre d'application c'est
difficile a faire d'une part, d'autre part ca ne fait
qu'ajouter du bruit qu'on peut filtrer au prix d'un facteur
constant.
Arnaud Meurgues writes:Question : l'introduction de nop aléatoires ne
pourraient-ils pas être plus simple tout en étant suffisante
pour empêcher de déduire quoique ce soit du temps d'analyse
?
De l'aleatoire asser sur pour ce genre d'application c'est
difficile a faire d'une part, d'autre part ca ne fait
qu'ajouter du bruit qu'on peut filtrer au prix d'un facteur
constant.
pour conclure mes commentaires sur cette 'simple' vérification
de passphrase, je recommanderais de:
- stocker (une fois pour toute) un hash du passphrase
référence (il peut ne pas être génant de l'avoir en clair si
le soft est vraiment protégé en lecture, mais il vaut mieux
éviter).
- boucler sur un nombre borné et petit d'essais (pas de while
infini)
- faire la saisie via un conteneur protégé (tel string) ou en
comptant les caractères reçus
- hasher le passphrase candidat
- faire une boucle (binaire ou booléenne) sans shortcut et sur
l'intégralité de la taille des digest générés. (seule cette
opération est sensible au temps).
- introduire un temps d'attente croissant entre chaque essai raté
- bloquer le service pendant un temps significativement long
après épuisement du nombre d'essais avant de le réinitialiser
(un service par agent ayant autorité de déblocage est souvent
non indispensable et toujours pénible).
pour conclure mes commentaires sur cette 'simple' vérification
de passphrase, je recommanderais de:
- stocker (une fois pour toute) un hash du passphrase
référence (il peut ne pas être génant de l'avoir en clair si
le soft est vraiment protégé en lecture, mais il vaut mieux
éviter).
- boucler sur un nombre borné et petit d'essais (pas de while
infini)
- faire la saisie via un conteneur protégé (tel string) ou en
comptant les caractères reçus
- hasher le passphrase candidat
- faire une boucle (binaire ou booléenne) sans shortcut et sur
l'intégralité de la taille des digest générés. (seule cette
opération est sensible au temps).
- introduire un temps d'attente croissant entre chaque essai raté
- bloquer le service pendant un temps significativement long
après épuisement du nombre d'essais avant de le réinitialiser
(un service par agent ayant autorité de déblocage est souvent
non indispensable et toujours pénible).
pour conclure mes commentaires sur cette 'simple' vérification
de passphrase, je recommanderais de:
- stocker (une fois pour toute) un hash du passphrase
référence (il peut ne pas être génant de l'avoir en clair si
le soft est vraiment protégé en lecture, mais il vaut mieux
éviter).
- boucler sur un nombre borné et petit d'essais (pas de while
infini)
- faire la saisie via un conteneur protégé (tel string) ou en
comptant les caractères reçus
- hasher le passphrase candidat
- faire une boucle (binaire ou booléenne) sans shortcut et sur
l'intégralité de la taille des digest générés. (seule cette
opération est sensible au temps).
- introduire un temps d'attente croissant entre chaque essai raté
- bloquer le service pendant un temps significativement long
après épuisement du nombre d'essais avant de le réinitialiser
(un service par agent ayant autorité de déblocage est souvent
non indispensable et toujours pénible).
les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string= >
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
different, non ?
c'est même une certitude ! j'ai "expliqué" que la longueur de la plus
les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string= >
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
different, non ?
c'est même une certitude ! j'ai "expliqué" que la longueur de la plus
les 2 opèrent donc en temps non constant; temps proportionnel à la plus
petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
pour string= >
Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
different, non ?
c'est même une certitude ! j'ai "expliqué" que la longueur de la plus
J'avoue que moi, il y a un truc que je n'ai pas compris dans
l'affaire. Pourquoi est-ce que je m'amuserai à mesurer les temps
de strcmp (de l'extérieur du programme, ce qui n'est pas
évident, vue que les aléas des temps perdus dans les
entrées/sorties et le schéduleur risquent d'être plusieurs
ordres de grandeur plus importantes), quand il me suffit de
faire strings sur l'exécutable, et alors, le mot de passe
apparaît en claire.
Il y a beaucoup de niveau de sécurité. C'est clair que si je me
sers de strcmp directement sur le mot de passe, j'ai un niveau
assez faible. Mais les variations dans le temps d'exécution de
strcmp est loin d'être le maillon le plus faible. Si on accepte
que le programme initial ne présente pas suffisamment de
sécurité pour l'application en question, on commencerait sans
doute par ne pas lire le mot de passe sur stdin/cin, mais plutôt
sur une liaison sécurisée dont on peut vérifier la provenance,
et qui assure que toute communication sur un reseau est
encryptée.
Et on ne comparerait pas les mots de passe eux-même,
mais un hachage ou un encryptage à sens unique (MD5, SHA1, ou
Et, sans doute, on essaierait d'abord à faire un programme qui
marche, sans erreurs. S'acharner sur les variations dans le
temps d'exécution de strcmp, quand on a un débordement de
buffer, me semble ne pas savoir gerer les priorités.
J'avoue que moi, il y a un truc que je n'ai pas compris dans
l'affaire. Pourquoi est-ce que je m'amuserai à mesurer les temps
de strcmp (de l'extérieur du programme, ce qui n'est pas
évident, vue que les aléas des temps perdus dans les
entrées/sorties et le schéduleur risquent d'être plusieurs
ordres de grandeur plus importantes), quand il me suffit de
faire strings sur l'exécutable, et alors, le mot de passe
apparaît en claire.
Il y a beaucoup de niveau de sécurité. C'est clair que si je me
sers de strcmp directement sur le mot de passe, j'ai un niveau
assez faible. Mais les variations dans le temps d'exécution de
strcmp est loin d'être le maillon le plus faible. Si on accepte
que le programme initial ne présente pas suffisamment de
sécurité pour l'application en question, on commencerait sans
doute par ne pas lire le mot de passe sur stdin/cin, mais plutôt
sur une liaison sécurisée dont on peut vérifier la provenance,
et qui assure que toute communication sur un reseau est
encryptée.
Et on ne comparerait pas les mots de passe eux-même,
mais un hachage ou un encryptage à sens unique (MD5, SHA1, ou
Et, sans doute, on essaierait d'abord à faire un programme qui
marche, sans erreurs. S'acharner sur les variations dans le
temps d'exécution de strcmp, quand on a un débordement de
buffer, me semble ne pas savoir gerer les priorités.
J'avoue que moi, il y a un truc que je n'ai pas compris dans
l'affaire. Pourquoi est-ce que je m'amuserai à mesurer les temps
de strcmp (de l'extérieur du programme, ce qui n'est pas
évident, vue que les aléas des temps perdus dans les
entrées/sorties et le schéduleur risquent d'être plusieurs
ordres de grandeur plus importantes), quand il me suffit de
faire strings sur l'exécutable, et alors, le mot de passe
apparaît en claire.
Il y a beaucoup de niveau de sécurité. C'est clair que si je me
sers de strcmp directement sur le mot de passe, j'ai un niveau
assez faible. Mais les variations dans le temps d'exécution de
strcmp est loin d'être le maillon le plus faible. Si on accepte
que le programme initial ne présente pas suffisamment de
sécurité pour l'application en question, on commencerait sans
doute par ne pas lire le mot de passe sur stdin/cin, mais plutôt
sur une liaison sécurisée dont on peut vérifier la provenance,
et qui assure que toute communication sur un reseau est
encryptée.
Et on ne comparerait pas les mots de passe eux-même,
mais un hachage ou un encryptage à sens unique (MD5, SHA1, ou
Et, sans doute, on essaierait d'abord à faire un programme qui
marche, sans erreurs. S'acharner sur les variations dans le
temps d'exécution de strcmp, quand on a un débordement de
buffer, me semble ne pas savoir gerer les priorités.
#include <stdio.h>
int main() {
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
printf("cnt=%dnpw='%s'n", cnt, pw);
}
$ ./leSoftQuiVerifieLePassphrase < /dev/null
cnt
pw='ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
$ ./leSoftQuiVerifieLePassphrase < /dev/zero
cnt
pw=''
$ printf ABCD | ./leSoftQuiVerifieLePassphrase
cnt
pw='ABCDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
L'incohérence entre la taille des donnees d'entree et la valeur de cnt,
ainsi que la presence des ÿ a l'affichage me suggere qu'il faut encore
faire quelque chose ici avant de passer aux problemes d'attaque
cryptographiques.
#include <stdio.h>
int main() {
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
printf("cnt=%dnpw='%s'n", cnt, pw);
}
$ ./leSoftQuiVerifieLePassphrase < /dev/null
cnt
pw='ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
$ ./leSoftQuiVerifieLePassphrase < /dev/zero
cnt
pw=''
$ printf ABCD | ./leSoftQuiVerifieLePassphrase
cnt
pw='ABCDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
L'incohérence entre la taille des donnees d'entree et la valeur de cnt,
ainsi que la presence des ÿ a l'affichage me suggere qu'il faut encore
faire quelque chose ici avant de passer aux problemes d'attaque
cryptographiques.
#include <stdio.h>
int main() {
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
printf("cnt=%dnpw='%s'n", cnt, pw);
}
$ ./leSoftQuiVerifieLePassphrase < /dev/null
cnt
pw='ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
$ ./leSoftQuiVerifieLePassphrase < /dev/zero
cnt
pw=''
$ printf ABCD | ./leSoftQuiVerifieLePassphrase
cnt
pw='ABCDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'
L'incohérence entre la taille des donnees d'entree et la valeur de cnt,
ainsi que la presence des ÿ a l'affichage me suggere qu'il faut encore
faire quelque chose ici avant de passer aux problemes d'attaque
cryptographiques.
Assez grosse, apparamment, que tu n'as pas réussi à le faire
correctement. Michel a déjà signalé le problème de EOF. Il y a
aussi la question du contenu réel du buffer : a priori, il
faudrait soit ajouter un ' ' à la fin (et la place pour ce ' '
n'est pas prévu -- c'est une source classique de débordement de
buffer), soit remplir la reste du buffer avec des caractères de
rembourage. Il y a aussi la question de l'état où tu laisses le
flux. (Si l'utilisateur entre plus de vingt caractères, ce sont
des lectures plus tard dans le programme qui va les voir.)
Alors que :
std::string line ;
std::getline( std::cin, line ) ;
line.resize( 20, ' ' ) ;
résoud tous ces problèmes. En trois lignes, et d'une façon bien
plus lisible.
Vanter une solution compliquée qui ne marche pas, par rapport à
une solution simple qui march, c'est bien une faute coupable, je
crois.
Quel compilateur n'est pas fourni avec la bibliothèque
standard aujourd'hui ? (Je parle, évidemment, des
Le rapport, c'est simple. Combien de temps va-t-on passer
là-dedans ? Et est-ce que l'utilisation de std::string va le
ralentir d'une façon mesurable, c-à-d plus de quelque percent du
Assez grosse, apparamment, que tu n'as pas réussi à le faire
correctement. Michel a déjà signalé le problème de EOF. Il y a
aussi la question du contenu réel du buffer : a priori, il
faudrait soit ajouter un ' ' à la fin (et la place pour ce ' '
n'est pas prévu -- c'est une source classique de débordement de
buffer), soit remplir la reste du buffer avec des caractères de
rembourage. Il y a aussi la question de l'état où tu laisses le
flux. (Si l'utilisateur entre plus de vingt caractères, ce sont
des lectures plus tard dans le programme qui va les voir.)
Alors que :
std::string line ;
std::getline( std::cin, line ) ;
line.resize( 20, ' ' ) ;
résoud tous ces problèmes. En trois lignes, et d'une façon bien
plus lisible.
Vanter une solution compliquée qui ne marche pas, par rapport à
une solution simple qui march, c'est bien une faute coupable, je
crois.
Quel compilateur n'est pas fourni avec la bibliothèque
standard aujourd'hui ? (Je parle, évidemment, des
Le rapport, c'est simple. Combien de temps va-t-on passer
là-dedans ? Et est-ce que l'utilisation de std::string va le
ralentir d'une façon mesurable, c-à-d plus de quelque percent du
Assez grosse, apparamment, que tu n'as pas réussi à le faire
correctement. Michel a déjà signalé le problème de EOF. Il y a
aussi la question du contenu réel du buffer : a priori, il
faudrait soit ajouter un ' ' à la fin (et la place pour ce ' '
n'est pas prévu -- c'est une source classique de débordement de
buffer), soit remplir la reste du buffer avec des caractères de
rembourage. Il y a aussi la question de l'état où tu laisses le
flux. (Si l'utilisateur entre plus de vingt caractères, ce sont
des lectures plus tard dans le programme qui va les voir.)
Alors que :
std::string line ;
std::getline( std::cin, line ) ;
line.resize( 20, ' ' ) ;
résoud tous ces problèmes. En trois lignes, et d'une façon bien
plus lisible.
Vanter une solution compliquée qui ne marche pas, par rapport à
une solution simple qui march, c'est bien une faute coupable, je
crois.
Quel compilateur n'est pas fourni avec la bibliothèque
standard aujourd'hui ? (Je parle, évidemment, des
Le rapport, c'est simple. Combien de temps va-t-on passer
là-dedans ? Et est-ce que l'utilisation de std::string va le
ralentir d'une façon mesurable, c-à-d plus de quelque percent du