Namespaces
Variants

std:: ungetc

From cppreference.net
< cpp ‎ | io ‎ | c
Défini dans l'en-tête <cstdio>
int ungetc ( int ch, std:: FILE * stream ) ;

Si ch n'est pas égal à EOF , pousse le caractère ch (réinterprété comme unsigned char ) dans le tampon d'entrée associé au flux stream de telle manière que les opérations de lecture ultérieures sur stream récupéreront ce caractère. Le périphérique externe associé au flux n'est pas modifié.

Les opérations de repositionnement de flux std::fseek , std::fsetpos , et std::rewind annulent les effets de ungetc .

Si ungetc est appelée plus d'une fois sans lecture ou repositionnement intermédiaire, elle peut échouer (en d'autres termes, une mémoire tampon de rappel de taille 1 est garantie, mais toute mémoire tampon plus grande est définie par l'implémentation). Si plusieurs appels réussis de ungetc sont effectués, les opérations de lecture récupèrent les caractères remis en mémoire dans l'ordre inverse des appels à ungetc

Si ch est égal à EOF , l'opération échoue et le flux n'est pas affecté.

Un appel réussi à ungetc efface le drapeau de statut de fin de fichier std::feof .

Un appel réussi à ungetc sur un flux binaire décrémente l'indicateur de position du flux de un (le comportement est indéterminé si l'indicateur de position du flux était zéro).

Un appel réussi à ungetc sur un flux de texte modifie l'indicateur de position du flux de manière non spécifiée, mais garantit qu'après que tous les caractères repoussés soient récupérés par une opération de lecture, l'indicateur de position du flux est égal à sa valeur avant ungetc .

Table des matières

Paramètres

ch - caractère à replacer dans le tampon de flux d'entrée
stream - flux de fichier dans lequel replacer le caractère

Valeur de retour

En cas de succès ch est retourné.

En cas d'échec, EOF est retourné et le flux donné reste inchangé.

Notes

La taille du tampon de pushback varie en pratique de 4k (Linux, MacOS) à aussi peu que 4 (Solaris) ou le minimum garanti de 1 (HPUX, AIX).

La taille apparente du tampon de retour en arrière peut être plus grande si le caractère qui est repoussé est égal au caractère existant à cet emplacement dans la séquence de caractères externe (l'implémentation peut simplement décrémenter l'indicateur de position de lecture du fichier et éviter de maintenir un tampon de retour en arrière).

Exemple

démontre l'utilisation de std::ungetc dans son objectif original : implémenter std::scanf

#include <cctype>
#include <cstdio>
void demo_scanf(const char* fmt, std::FILE* s)
{
    while (*fmt != '\0') {
        if (*fmt == '%') {
            switch (*++fmt) {
                case 'u': {
                    int c{};
                    while (std::isspace(c=std::getc(s))) {}
                    unsigned int num{};
                    while (std::isdigit(c)) {
                        num = num*10 + c-'0';
                        c = std::getc(s);
                    }
                    std::printf("%%u scanned %u\n", num);
                    std::ungetc(c, s);
                    break;
                }
                case 'c': {
                    int c = std::getc(s);
                    std::printf("%%c scanned '%c'\n", c);
                    break;
                }
            }
        } else {
            ++fmt;
        }
    }
}
int main()
{
    if (std::FILE* f = std::fopen("input.txt", "w+")) {
        std::fputs("123x", f);
        std::rewind(f);
        demo_scanf("%u%c", f);
        std::fclose(f);
    }
}

Sortie :

%u scanned 123
%c scanned 'x'

Voir aussi

obtient un caractère d'un flux de fichier
(fonction)
Documentation C pour ungetc