2013-06-13 4 views
0

Привет всем, что я пытаюсь сделать, это scanf строка для 2 переменных структуры, но при запуске кода она просто проходит, хотя scanf (оба они), и переходит к printf.scanf не распознает% 59 [^ n]

Мой код выглядит следующим образом:

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); 
} 
+2

Добро пожаловать в Переполнение стека. Вскоре прочитайте [FAQ]. Вы всегда можете отредактировать свой собственный вопрос; На этот раз я пересадил дополнительную информацию в этот вопрос, но вы тоже могли бы это сделать. Поскольку вы не проверяете возвращаемое значение из 'scanf()', вы не можете сказать, счастлив он или нет. Какова была операция чтения до этого? Он удостоверился, что прочитана новая строка? –

ответ

0

Вы пытаетесь прочитать 60 символов и указывает, что на 59 в scanf заявлении? Тогда ваш scanf ошибочен. Измените его на: scanf ("%s", novo->nome); и он должен работать. То же самое с другим scanf.

+0

Thx для вашего ответа, но я уже пробовал это, и результат был, если бы я ввел имя, например, мое «Ricardo Sacramento», пространство в середине будет концом первого scanf, а затем в моем результате printf будет ricardo - sacramento и целью является появление имени «ricardo Sacramento» - например, «описание». Я хочу, чтобы scanf читал до появления \ n или до 59 символов. –

+0

Затем вы можете изменить его на 'gets' или' fgets'.Это позволит вам читать до новой строки. Вы можете использовать 'fgets (novo-> nome, sizeof (novo-> nome), stdin);' и вы должны быть хороши, но, возможно, придется заменить символ новой строки символа 'NULL'. – unxnut

+0

Чтобы удалить символ новой строки в результате 'fgets', добавьте следующую инструкцию:' novo-> nome [strlen (novo-> nome) -1] = NULL; ' – unxnut

-1

Вот полный пример, чтение две строки из стандартного ввода, а затем с помощью sscanf, чтобы удалить символ новой строки и их печати:

#include <stdio.h> 

struct { 
    char first[60]; 
    char second[60]; 
} store; 

int main(int argc, char ** argv) { 
    char buffer[60]; 

    printf("write something: "); 
    fgets(buffer, 60, stdin); 
    sscanf(buffer, "%s", store.first); 

    printf("write something else: "); 
    fgets(buffer, 60, stdin); 
    sscanf(buffer, "%s", store.second); 

    printf("you wrote: %s then %s\n", store.first, store.second); 

    return 0; 
} 
+0

Он не хочет читать« не более 59 символов; он хочет читать не более 59 символов, отличных от новой строки, за которыми следует новая строка (а не то, что он когда-либо сможет определить, действительно ли соответствие новой строки). –

+0

Вы правы, мой ответ был глупым ... переписал его, чтобы использовать fgets – Guillaume

+0

Я хочу, чтобы иметь возможность читать строку с промежутком между ними для максимум 59 символов. –

4

Проблема состоит в том, что пустое пространство (в том числе и переводы строк) в scanf() строк формата ведет себя особенно — это означает произвольную последовательность символов пробела.

Когда он запрашивает Nome:, вы можете ввести имя ('Александр Великий') и новую строку, но 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(), чтобы разобрать ее; что часто работает лучше.

+0

+1 для «use' fgets() 'для чтения строки и' sscanf() 'для ее анализа" – chux

Смежные вопросы