2010-03-02 3 views
9

Я довольно новичок в C, и у меня возникла проблема с вводом данных в программу.Вход в C. Scanf до получения. Проблема

Мой код:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

    printf("Input your name: "); 
    gets(b); 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 

Это позволяет для ввода ID, но он просто пропускает остальную часть входных данных. Если я изменю заказ следующим образом:

printf("Input your name: "); 
    gets(b); 

    printf("Input your ID: "); 
    scanf("%d", &a); 

Будет работать. Хотя, я НЕ МОГУ поменять порядок, и мне это нужно как есть. Кто-нибудь может мне помочь ? Возможно, мне нужно использовать некоторые другие функции. Благодаря!

+1

получает (3): «получает() функция не может быть надежно использован Из-за его отсутствия проверки границ, и невозможность для вызывающей программы в. надежно определяют длину следующей входящей линии, использование этой функции позволяет злоумышленникам произвольно изменять функциональность запущенной программы - - через атаку переполнения буфера. Настоятельно предлагается , что функция fgets() будет использоваться в все случаи. FSA.) « Не используйте его. –

+3

Короче: если вы используете 'get', летающие бешеные атакующие оцелоты вырвут ваши глаза. Так не надо. –

+2

'scanf' is ** evil ** - http://c-faq.com/stdio/scanfprobs.html – jschmier

ответ

10

Try:.

scanf("%d\n", &a); 

получает только читает '\ п', что Scanf листов Кроме того, вы должны использовать fgets не получает: http://www.cplusplus.com/reference/clibrary/cstdio/fgets/, чтобы избежать возможного переполнения буфера.

Edit:

если выше не работает, попробуйте:

... 
scanf("%d", &a); 
getc(stdin); 
... 
+0

Гм. Я пробовал scanf («% d \ n», &a);, но, похоже, он не работает. После ввода идентификатора я просто не вижу, как программа делает что-то еще. – Dmitri

+0

Wow! Спасибо! Это работало безупречно! Спасибо, – Dmitri

7

scanf не потребляет символ новой строки и, таким образом, естественный враг fgets. Не складывайте их без хорошего взлома. Обе эти опции будут работать:

// Option 1 - eat the newline 
scanf("%d", &a); 
getchar(); // reads the newline character 

// Option 2 - use fgets, then scan what was read 
char tmp[50]; 
fgets(tmp, 50, stdin); 
sscanf(tmp, "%d", &a); 
// note that you might have read too many characters at this point and 
// must interprete them, too 
+0

Спасибо большое! – Dmitri

+0

Кроме того, использование 'scanf ("% d% * c ", & a)' должно работать. Термин '% * c' вызывает 'scanf' для чтения в одном символе (новая строка), но звездочка приводит к отбрасыванию значения. Это заставит' scanf' есть новую строку, не требуя отдельного вызова функции. – bta

+0

Вы представляете оба варианта, как если бы они были одинаковыми, но 'scanf' так сложно использовать правильно, что гораздо лучше не использовать его полностью (см. ссылку на comp.lang.c FAQ). Просто перейдите к опции 2. – jamesdlin

1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
     int a; 
     char b[20]; 
     printf("Input your ID: "); 
     scanf("%d", &a); 
     getchar(); 
     printf("Input your name: "); 
     gets(b); 
     printf("---------"); 
     printf("Name: %s", b); 
     return 0; 
} 



Note: 
    If you use the scanf first and the fgets second, it will give problem only. It will not read the second character for the gets function. 

    If you press enter, after give the input for scanf, that enter character will be consider as a input f or fgets. 
2

зсап не будет потреблять \ п так будет, занятой получает который следует за зсапом. запустите поток ввода после scanf, как это.

#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 
    fflush(stdin); 
    printf("Input your name: "); 
    gets(b); 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 
+2

Как fflush (stdin), так и fflush (NULL) в некоторых библиотеках C будет flush stdout и stderr, но это совершенно невозможно! –

0

Вы должны сделать это.

fgetc(stdin); 
    scanf("%c",&c); 
    if(c!='y') 
    { 
     break; 
    } 
    fgetc(stdin); 

читать ввод от scanf после прочтения.

0

Просто используйте 2 получает() функции

Если вы хотите использовать получает() после зсапЕ(), вы убедитесь, что вы используете 2 из получает() функции и для вышеприведенного случая написать код например:

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

//the change is here********************* 
    printf("Input your name: "); 
    gets(b); 
    gets(b); 
//the change is here********************* 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 

Для пояснения ([email protected]);

+0

добро пожаловать в SO! Пожалуйста, помните, что английский не является первым языком для всех здесь, поэтому старайтесь публиковать ответы, которые являются грамматически правильными, вместо того, чтобы использовать «u» для «вас», что не будет работать с Google Translate! –

0

scanf("%d", &a); не может прочитать возврат, потому что %d принимает только десятичное целое число. Поэтому вы добавляете \n в начале следующего scanf, чтобы игнорировать последние \n внутри буфера.

Затем scanf("\n%s", b); теперь может читать строку без проблем, но scanf останавливается, когда читает пробел. Итак, измените %s на %[^\n].Это означает: «читать Everthing но \n»

scanf("\n%[^\n]", b);

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

    printf("Input your name: "); 
    scanf("\n%[^\n]", b); 
    //first \n says to ignore last 'return' 
    //%[^\n] read until find a 'return' 
    printf("---------\n"); 
    printf("Name: %s\n\n", b); 

    system("pause"); 
    return 0; 
} 
+1

Пожалуйста, введите код. – coatless

+0

Explantion добавлено @Coatless –

0

scanf функция удаляет пробелы автоматически, прежде чем пытаться разобрать, кроме символов вещи. %c, %n, %[] - исключения, которые не удаляют ведущие пробелы.

gets читает новую строку, ранее добавленную scanf. Поймай символ новой строки, используя getchar();

scanf("%d", &a); 
getchar(); // catches the newline character omitted by scanf("%d") 
gets(b); 

https://wpollock.com/CPlus/PrintfRef.htm