問題は、フォーマット文字列内の空白 (改行を含む)scanf()
が独特の振る舞いをすることです — これは空白文字の任意のシーケンスを意味します。
プロンプトが表示さNome:
れたら、名前 (「Alexander the Great」) と改行を入力できますが、scanf()
空白ではない別の文字に遭遇するまで読み続けます。したがって、「アジアの征服者」と入力すると、プロンプトDescricao:
が表示され、空白以外の別の文字を入力するまで読み上げられ、終了します。
例えば:
$ ./name-prompt
Nome: Alexander The Great
Conqueror of Asia
Descricao: a
<<Alexander The Great>> - <<Conqueror of Asia>>
$
これはコードからのものです:
#include <stdio.h>
#include <stdlib.h>
struct s_Especialidade{
char nome[60];
char descricao[60];
struct s_Especialidade *proximo;
};
typedef struct s_Especialidade Especialidade;
typedef Especialidade *PESPECIALIDADE;
static
void novaEspecialidade(void)
{
PESPECIALIDADE novo = malloc(sizeof(Especialidade) );
printf("\nNome: ");
if (scanf("%59[^\n]\n", (novo->nome)) != 1)
printf("Oh, bother!\n");
printf("\nDescricao: ");
if (scanf("%59[^\n]\n", (novo->descricao)) != 1)
printf("Oh, bother!\n");
novo->proximo = NULL;
printf("\n<<%s>> - <<%s>>\n", novo->nome, novo->descricao);
free(novo);
}
int main(void)
{
novaEspecialidade();
return 0;
}
printf()
出力は改行で終わることに注意してください。それは一般的に良い考えです。
これを回避するには、scanf()
フォーマットを次のように変更します。
"%59[^\n]"
の後、scanf()
次と同等の操作を行います。
int c;
while ((c = getchar()) != EOF && c != '\n')
;
それを関数にパッケージ化します — おそらくgobble()
またはread_to_newline()
.
またはfgets()
、行を読み取っsscanf()
て解析するために使用します。その方がうまくいくことがよくあります。