0

こんにちは、私がやろうとしているのはscanf、2 つの構造体変数への文字列scanfですprintf

私のコードは次のとおりです。

struct s_Especialidade{
    char nome[60];
    char descricao[60];
    struct s_Especialidade *proximo;
};

typedef struct s_Especialidade Especialidade;
typedef Especialidade *PESPECIALIDADE; 

void novaEspecialidade()
{
    PESPECIALIDADE novo = malloc(sizeof(Especialidade) );
    int opcao=0;
    printf("\nNome: ");
    scanf("%59[^\n]\n", (novo->nome));
    printf("\nDescricao: ");
    scanf("%59[^\n]\n", (novo->descricao));
    novo->proximo = NULL;
    printf("\n%s - %s",novo->nome, novo->descricao);
}
4

3 に答える 3

4

問題は、フォーマット文字列内の空白 (改行を含む)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()て解析するために使用します。その方がうまくいくことがよくあります。

于 2013-06-13T16:54:13.353 に答える