AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79528408
Accepted
Akramat
Akramat
Asked: 2025-03-23 11:33:19 +0800 CST2025-03-23 11:33:19 +0800 CST 2025-03-23 11:33:19 +0800 CST

O que é um item de entrada no scanf?

  • 772

Estou aprendendo C e tentando entender como scanf funciona. Não consigo entender alguns termos: o termo "input item", "initial subsequence", "matching sequence". Estou lendo isto https://pubs.opengroup.org/onlinepubs/9699919799/functions/scanf.html . Diz:

Um item de entrada deve ser definido como a sequência mais longa de bytes de entrada (até qualquer largura máxima de campo especificada, que pode ser medida em caracteres ou bytes dependendo do especificador de conversão), que é uma subsequência inicial de uma sequência correspondente .

Suponha que no formato i tenha %d e no stdin 4.5 . O que é subsequência inicial e o que é sequência correspondente ? E o que é item de entrada ?

Pensei que o item de entrada é o que corresponde a esse especificador, ou seja, para %d os símbolos correspondentes são números (talvez sinais de + - no início), mas então ele diz:

Exceto no caso de um especificador de conversão %, o item de entrada (ou, no caso de uma especificação de conversão %n, a contagem de bytes de entrada) deve ser convertido para um tipo apropriado para o caractere de conversão. Se o item de entrada não for uma sequência correspondente , a execução da especificação de conversão falhará;

ou seja, o item de entrada pode não corresponder, o que significa que ele não consiste apenas em símbolos que correspondem ao especificador.

Então, você pode me explicar esses termos? E me dizer se é aqui que estou procurando documentação para funções C? Quais sites são os melhores lugares para ler documentação para funções C?

c
  • 4 4 respostas
  • 133 Views

4 respostas

  • Voted
  1. Best Answer
    Eric Postpischil
    2025-03-23T18:56:22+08:002025-03-23T18:56:22+08:00

    Um problema-chave com o qual este texto está lidando é que às vezes se uma sequência de caracteres corresponde ao padrão para uma conversão depende de caracteres ainda não lidos. Por exemplo, o texto de entrada “0x3” corresponde ao padrão para %x, mas o texto de entrada “0xy” não. No ponto em que lemos “0x”, “0x” por si só não corresponde ao padrão, e não sabemos se o próximo caractere formará uma sequência correspondente. Precisamos ler o próximo caractere para descobrir.

    Então a regra para quando scanfcontinua lendo caracteres não pode ser "Enquanto os caracteres corresponderem ao padrão de objetivo, continue lendo". Se essa fosse a regra, leríamos "0", veríamos que corresponde a uma possível entrada válida para %x, então leríamos "x", veríamos que "0x" não é uma entrada válida para %x, e pararíamos. Isso não funcionará, porque falha em ler "0x3", que é uma entrada válida para %x.

    A regra deve ser que scanfcontinua lendo enquanto a entrada puder ser uma sequência correspondente se os caracteres vindouros completarem uma correspondência. Uma maneira de dizer isso tecnicamente é que os caracteres lidos até agora são uma subsequência inicial de uma sequência correspondente.

    Suponha que no formato eu tenha %d e no stdin 4.5 . O que é subsequência inicial e o que é sequência correspondente? E o que é item de entrada?

    Uma sequência correspondente para %dé opcionalmente um “-”, então um ou mais dígitos decimais. Considere as sequências correspondentes “123” e “-123”. Subsequências iniciais de “123” são a string vazia, “1”, “12” e “123”. Subsequências iniciais de “-123” são a string vazia, “-”, “-1”, “-12” e “-123”. Então uma subsequência inicial de uma sequência correspondente para %dé opcionalmente um “-”, então zero ou mais dígitos decimais. Note que “-” é uma subsequência inicial, mas não uma sequência correspondente.

    É mais interessante considerar %e, onde “3.4e-5” é uma sequência correspondente, mas “3.4” ou “3.4ex” não é. Agora scanftem que ler dois caracteres onde não se sabe se haverá uma correspondência. Quando scanfleu “3.4”, essa é uma sequência correspondente, mas tem que continuar enquanto os caracteres formarem uma subsequência inicial. Em seguida, temos “3.4e”, que não é mais uma sequência correspondente, mas ainda é uma subsequência inicial. Então “3.4e-” também é uma subsequência inicial. Com “3.4e-5”, mais uma vez temos uma sequência correspondente, bem como uma subsequência inicial. scanfdeve continuar lendo. Se o próximo caractere for um espaço, “3.4e-5 ” não é uma subsequência inicial, então o espaço é rejeitado (e é “colocado de volta” no fluxo de entrada como se nunca tivesse sido lido), e “3.4e-5” é o item de entrada. Este item de entrada é uma sequência correspondente, então é convertido em um float.

    Agora considere ler “3.4ex”. Como acima, em “3.4e”, scanfdeve continuar lendo. Ele obtém o “x” e vê que “3.4ex” não é uma subsequência inicial. Ele rejeita o “x” e o coloca de volta no fluxo de entrada. Agora ele terminou de ler, e “3.4e” é o item de entrada. Esta não é uma sequência correspondente, então é uma falha de correspondência. scanfnão realiza uma conversão para isto, e ele retorna.

    Note que com “3.4ex”, se pudéssemos colocar de volta dois caracteres em vez de apenas um, poderíamos reverter para “3.4”, corresponder a isso para %e, e convertê-lo para float. No entanto, o padrão C não requer que os fluxos de E/S suportem mais de um caractere de put-back, e scanfé especificado para trabalhar com apenas um caractere de put-back. É por isso que scanfé especificado para ler até que uma correspondência seja impossível, então colocar de volta o caractere não correspondente, então ver se o que ele leu é uma correspondência. Se tivéssemos mais níveis de put-back, scanfpoderíamos ler até que uma correspondência seja impossível, então colocar de volta todos os caracteres necessários para reduzir a entrada para uma sequência correspondente, e então converter isso.

    (Observe que, conforme discutido nos comentários, algumas scanfimplementações não estão em conformidade com esta especificação do padrão C e podem retornar vários caracteres.)

    Quais são os melhores sites para ler documentação sobre funções C?

    Não há um único site que seja o melhor lugar, nem um pequeno conjunto de sites. O padrão C é o lugar mais confiável para ler sobre funções na biblioteca padrão C, mas entendê-las é informado pela teoria da ciência da computação e pela história do desenvolvimento da linguagem C. Com esta edição em scanf, a teoria sobre análise sintática, linguagens formais e máquinas de estados finitos é informativa sobre como um computador tem que ler caracteres para interpretá-los. Essas são partes do estudo de uma educação em ciência da computação, não algo que você obtém facilmente em sites com foco restrito.

    • 7
  2. user2357112
    2025-03-23T12:02:48+08:002025-03-23T12:02:48+08:00

    É um pouco confuso.

    Essencialmente, scanf lê bytes para um especificador de conversão até que o próximo byte não possa ser parte do que ele deveria ler para aquele especificador de conversão. Então ele olha o que foi lido, e esse é o item de entrada para aquele especificador de conversão. (Por baixo dos panos, ele provavelmente "deslê" o próximo byte com ungetc.)


    "Sequência de correspondência" significa qualquer sequência de caracteres que corresponderia à especificação de conversão. Não é restrito a sequências de caracteres que realmente aparecem na entrada. Por exemplo, 0e 0xffsão ambas sequências de correspondência para a especificação de conversão %x.

    Uma "subsequência inicial de uma sequência correspondente" significa qualquer sequência de caracteres que pode ser o início de uma sequência correspondente. Por exemplo, 0, 0x, e 0xffsão todas subsequências iniciais da sequência correspondente 0xffpara a especificação de conversão %x. Elas também são subsequências iniciais de muitas outras sequências correspondentes, como 0xff00ou 0xff1.

    Um item de entrada é a sequência mais longa de caracteres de entrada que é uma subsequência inicial de uma sequência correspondente. Por exemplo, se a entrada for 0xgoosee scanf estiver processando um especificador de conversão de %x, então o item de entrada é 0x. Não é 0, embora 0seja uma sequência correspondente, e não é nada mais longo que 0x, porque nada mais longo poderia ser o início de uma sequência correspondente.

    • 3
  3. 4386427
    2025-03-23T15:35:03+08:002025-03-23T15:35:03+08:00

    sequência de correspondência

    é qualquer sequência de caracteres que seja uma representação válida para o especificador de conversão usado. Não se refere à entrada real. Refere-se a toda e qualquer sequência válida (também conhecida como correspondente).

    Exemplos %dde sequências correspondentes são 123456, 987654e muitos, muitos outros.

    subsequência inicial

    é uma parte (ou toda) de outra sequência começando do caractere mais à esquerda, ou seja, o caractere inicial.

    Por exemplo, para a sequência 1234, as subsequências iniciais são 1, 12, 123e1234

    item de entrada

    é a maior subsequência inicial de uma sequência correspondente. Em outras palavras, os caracteres que serão convertidos e então armazenados na variável fornecida.

    Por exemplo, para o 1234Zespecificador de sequência e conversão, %da maior subsequência inicial de uma sequência correspondente é 1234.

    • 1
  4. chux
    2025-03-23T19:49:43+08:002025-03-23T19:49:43+08:00

    Um conjunto de testes para ajudar a avaliar as respostas em comparação com o código real.

    #include <assert.h>
    #include <stdio.h>
    
    int main() {
      const char *fname = "c:/tmp/junk1.txt";
      const char *s = "3.4ex";
      float x = 42.0f;  // Some value
      FILE *f = fopen(fname, "w");
      assert(f);
      fprintf(f, "%s", s);
      fclose(f);
    
      f = freopen(fname, "r", stdin);
      assert(f);
      int cnt = scanf("%f", &x);
      printf("Test:\"%s\", Conversion count:%d, value:%f", s, cnt, x);
      fflush(stdout);
      int ch = fgetc(f);
      printf(", Next character:%d %c\n", ch, ch);
      return 0;
    }
    

    Exemplo de saída: (Observe que esta saída certamente não está em conformidade com a especificação C.)

    Test:"3.4ex", Conversion count:1, value:3.400000, Next character:101 e
    
    • 1

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve