Pergunta

Eu tenho tido muitos problemas tentando descobrir como usar scanf(). Parece funcionar bem com números inteiros, sendo scanf("%d", &i) bastante para a frente.

Onde eu estou correndo em questões está usando scanf() em loops tentando ler a entrada. Por exemplo:

do {
  printf("counter: %d: ", counter);
  scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
  1. Quando eu entro em uma entrada validamente estruturado como c P101, parece-circuito novamente antes de me avisar. Isto parece acontecer mesmo com uma única:

    scanf("%c", &c) 
    

    em um loop while. Ele vai fazer o circuito duas vezes antes de me avisar novamente. O que está tornando-circuito duas vezes, e como faço para pará-lo?

  2. Quando eu entro em menos quantidade de entrada que programaticamente não teria outro personagem ou número como q, enter parece-me pedir para entrar mais. Como faço para obter scanf() para processar as duas entradas de caracteres individuais e duplos?

Foi útil?

Solução

Quando você entra "c P101" o programa realmente recebe "c P101\n". A maioria dos especificadores de conversão pular líder espaço em branco incluindo novas linhas, mas %c não. A primeira vez em torno de tudo para cima até o "\n" é lido, pela segunda vez em torno do "\ n" é lido na command, "c" é lido na prefix, e "P" é deixado que não é um número tão a conversão falha e "P101\n" é deixado no fluxo. O tempo próximo "P" é armazenada em comandos, "1" é armazenado em prefixo, e 1 (a partir do restante "01") é armazenado na entrada com o "\n" ainda sobre o fluxo para a próxima vez. Você pode corrigir esse problema, colocando um espaço no início da cadeia de formato que irá ignorar qualquer líder espaço em branco incluindo novas linhas.

Uma coisa semelhante está acontecendo para o segundo caso, quando você digitar "q", "q\n" é introduzido na corrente, a primeira vez em torno do "q" é lido, pela segunda vez o "\n" é lido, apenas na terceira chamada é o segundo "q" ler, você pode evitar o problema novamente, adicionando um caractere de espaço no início da seqüência de formato.

A melhor maneira de fazer isso seria usar algo como fgets () para processar uma linha de cada vez e, em seguida, use sscanf () para fazer a análise.

Outras dicas

É realmente quebrado! Eu não sabia que ele

#include <stdio.h>

int main(void)
{
    int counter = 1;
    char command, prefix;
    int input;

    do 
    {
        printf("counter: %d: ", counter);
        scanf("%c %c%d", &command, &prefix, &input);
        printf("---%c %c%d---\n", command, prefix, input);
        counter++;
    } while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
 c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
 g3---

A saída parece se encaixar com a resposta de Robert.

Depois de ter a seqüência que contém a linha. ou seja, "C P101", você pode usar as habilidades análise de sscanf.

Veja: http://www.cplusplus.com/reference/clibrary/cstdio/sscanf. html

Para a pergunta 1, eu suspeito que você tem um problema com seu printf(), já que não há terminação "\ n".

O comportamento padrão do printf é para o buffer de saída até que ele tem uma linha completa. Isso é menos que você altere explicitamente o buffer em stdout.

Para a pergunta 2, você acabou de atingir um dos maiores problemas com scanf(). A menos que sua entrada corresponde exatamente a seqüência de digitalização que você especificou, seus resultados vão ser nada como o que você espera.

Se você tem uma opção que você terá melhores resultados (e menos problemas de segurança) por ignorar scanf() e fazer a sua própria análise. Por exemplo, o uso fgets() para ler uma linha inteira em uma string, e depois processar os campos individuais do string -. Talvez até mesmo usando sscanf()

Talvez usando um loop while, não um fazer ... loop while vai ajudar. Desta forma, a condição é testada antes da execução do código. Tente o seguinte trecho de código:

 while(command != 'q')
    {
        //statements
    }

Além disso, se você sabe o comprimento da corda antes do tempo, 'para' loops podem ser muito mais fácil de trabalhar do que 'enquanto' loops. Existem também algumas formas mais complicadas para determinar dinamicamente o comprimento também.

Como um discurso final: scanf() não "chupar". Ele faz o que faz e isso é tudo. fgets() é muito perigoso (embora conveniente para aplicações sem risco), uma vez que não nativamente fazer qualquer verificação da entrada. É muito comumente conhecido como um ponto de explorar, especificamente buffer overflow ataques, substituindo o espaço em registos não alocados para essa variável. Portanto, se você optar por usá-lo, passar algum tempo colocando algum sólido verificação de erros / correção.

Espero que isso ajude alguém no futuro desde que eu supor que você tem sua manipulação a agora! ;)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top