2
votes

La «largeur maximale du champ» scanf comprend des espaces?

Supposons que nous ayons

int n;
sscanf(" 42", "%2d", &n);

Si n doit être égal à 4 (l'espace blanc représenté par le "% 2d") ou 42 (espace blanc ignoré, rendant scanf lu 3 caractères)?

ideone implementation lit 3 caractères p>


1 commentaires

À partir de la page de manuel sur MacOS: "Avant le début de la conversion, la plupart des conversions ignorent les espaces blancs; cet espace blanc n'est pas compté dans la largeur du champ."


3 Réponses :


1
votes

Depuis la page de manuel BSD:

En plus de ces indicateurs, il peut y avoir une largeur de champ maximale facultative, exprimé sous forme d'entier décimal, entre le% et la conversion. Si aucune largeur n'est étant donné, une valeur par défaut de `` infini '' est utilisée (à une exception près, ci-dessous); autrement tout au plus ce nombre d'octets est analysé lors du traitement de la conversion. Dans le cas de les conversions lc, ls et l [ la largeur du champ spécifie le nombre maximum de caractères multi-octets qui seront analysés. Avant le début de la conversion, la plupart des conversions ignorent les espaces blancs; cet espace blanc n'est pas compté dans le champ largeur.

La page de manuel Linux a

Un entier décimal facultatif qui spécifie la largeur maximale du champ. En train de lire de caractères s'arrête soit lorsque ce maximum est atteint, soit en cas de non caractère est trouvé, selon la première éventualité. La plupart des conversions ignorent l'initial les caractères d'espacement (les exceptions sont notées ci-dessous), et ceux-ci sont supprimés les caractères ne comptent pas dans la largeur maximale du champ. Les conversions d'entrée de chaîne stockent un octet nul de fin ('\ 0') pour marquer la fin de l'entrée; la la largeur maximale du champ n'inclut pas ce terminateur.

tous deux spécifient que l'espace blanc ne compte pas dans la largeur du champ.


0 commentaires

4
votes

La spécification POSIX pour sscanf () < / a> est assez clair sur le traitement:

Le format est une chaîne de caractères,… composée de zéro ou plusieurs directives. Chaque directive est composée de l'un des éléments suivants: un ou plusieurs caractères d'espacement ( , , , , ou ); un caractère ordinaire (ni «% » ni un caractère d'espace blanc); ou une spécification de conversion. Chaque spécification de conversion est introduite par le caractère '% ' [CX] ⌦ ou la séquence de caractères "% n $", ⌫ après quoi les éléments suivants apparaissent dans l'ordre:

Une directive qui est une spécification de conversion définit un ensemble de séquences d'entrée correspondantes, comme décrit ci-dessous pour chaque caractère de conversion. Une spécification de conversion doit être exécutée dans les étapes suivantes.

Les caractères d'espacement en entrée (comme spécifié par isspace ) doivent être ignorés, sauf si la spécification de conversion inclut un [, c , < code> C ou spécificateur de conversion n .

Un élément doit être lu à partir de l'entrée, sauf si la spécification de conversion inclut un spécificateur de conversion n . Un élément d'entrée doit être défini comme la plus longue séquence d'octets d'entrée (jusqu'à toute largeur de champ maximale spécifiée, qui peut être mesurée en caractères ou en octets en fonction du spécificateur de conversion) qui est une sous-séquence initiale d'une séquence correspondante. Le premier octet, le cas échéant, après l'élément d'entrée doit rester non lu. Si la longueur de l'élément d'entrée est 0, l'exécution de la spécification de conversion échouera; cette condition est un échec de correspondance, sauf si la fin de fichier, une erreur de codage ou une erreur de lecture a empêché l'entrée du flux, auquel cas il s'agit d'un échec d'entrée.

Si l'espace blanc est ignoré par une spécification de conversion (%… ), il n'est pas compté comme faisant partie de la largeur du champ; le saut se produit avant tout comptage.

La spécification équivalente en C11 §7.21.6.2 Le fscanf est très similaire (mais elle n'inclut pas le balisage 'C extension', bien sûr).


0 commentaires

3
votes

La 'largeur maximale du champ' scanf comprend des espaces?

Oui pour [ et c .
Non pour les autres prescripteurs.
"% n" ne s'applique pas.

Le fscanf () (C11dr §7.21.6.2 7-9)

7 ... Une spécification de conversion est exécutée dans les étapes suivantes:

8 Les caractères d'espacement en entrée (comme spécifié par la fonction isspace) sont ignorés , sauf si la spécification inclut un [, c , ou spécificateur n .

9 Un élément d'entrée est lu à partir du flux, ... Un élément d'entrée est défini comme la plus longue séquence de caractères d'entrée qui ne dépasse aucun champ spécifié largeur et ....

La largeur s'applique après la consommation de caractères d'espace blanc en entrée.

De plus, au fur et à mesure que je lis les spécifications, si la conversion échoue, les caractères d'espace blanc d'entrée sont restés consommés.


7 commentaires

La dernière phrase a ajouté un nouveau peu d'apprentissage. Devra tester si cela est systématiquement implémenté par les différents compilateurs. Lâchera une note s'il y en a là.


@ DavidC.Rankin Attendez avec impatience vos découvertes.


Bien sûr, l'espace blanc reste consommé - car cela se fait avec ungetc qui n'a qu'un seul caractère garanti de retour. @ DavidC.Rankin


Wow, nouvelle révélation lors de la lecture de la documentation pour ungetc - l'argument ungetc doit être unsigned char .


@AnttiHaapala fscanf () repousser comme si avec ungetc () et ungetc () a "Un caractère de refoulement est garanti. Si le ungetc est appelée trop de fois sur le même flux sans opération de lecture ou de positionnement de fichier sur ce flux, l'opération peut échouer. " OMI, des mots farfelus qui permettent d'en repousser plus d'un, parfois . IOWs, comportement défini par la mise en œuvre.


@chux mon point est que la spécification requise ne va pas au-delà de ce que vous pouvez réaliser avec un seul caractère.


@chux - gcc / clang / VS10 (sur SuSE, Arch et Win7) montrent tous le bon comportement (je ne peux pas croire que l'un d'eux ne l'ait pas dérangé :) fscanf whitespace check - code de vérification utilisé (le lien expire: lundi 6 mai 22:55:32 CDT 2019)