2015-07-09 2 views
0

Я пытаюсь научиться программированию на C с некоторыми практическими упражнениями. Это, например, должно читать 2 серии номеров (дней месяца), вводимых пользователем.C: scanf и выход программы

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

Почему?

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

int main() 
{ 
    int f = 0; 
    int days1[31]; 
    int days2[31]; 
    printf("Insert first serie \n"); 
    while(scanf("%d",&days1[f])) { 
    f++; 
    } 

    // the following scanf loop is skipped 
    f = 0; 
    printf("Insert second serie \n"); 
    while(scanf("%d",&days2[f])) { 
    f++; 
    } 
} 

благодарит

+0

Я только что протестировал его, и он даже не вышел из первого цикла, я просто могу ввести номера. – moffeltje

+0

@moffeltje: То же самое здесь. – WedaPashi

+1

попытайтесь ввести письмо вместо числа, оно выйдет – Val

ответ

4

Читайте документацию по scanf. Он возвращает количество отсканированных элементов, и вы должны их хранить и проверять. Он может возвращать -1 при отказе (и это рассматривается как истинное значение), а затем не потребляет никаких данных. Спецификатор преобразования %n часто полезен и недостаточно известен.

Так код

while(f < 31 && scanf("%d",&days1[f])>0) f++; 

Но вы, вероятно, нужно, чтобы закончить первую серию с чем-то, что делает scanf неудачу, а затем вам нужно, чтобы пропустить что-то. Вы должны определить и документировать соглашение об этом. Давайте представим, что вы наберете точкой с запятой ; то вы код возможно:

f=0; 
    while(f < 31 && scanf("%d",&days1[f])>0) f++; 
    if (getchar() != ';') exit(EXIT_FAILURE); 
    f=0; 
    while(f < 31 && scanf("%d",&days2[f])>0) f++; 

Я не уверен, что выше работа. Возможно, вам придется заботиться о пробелах или пустых строках. Вы можете прочитать каждую отдельную строку с fgets или getline и проанализировать каждую строку (используя sscanf или strtol).

На самом деле, я бы рекомендовал объявить достаточно большой буфер char buf[256];, используйте fgets читать единственную строку, содержащую все серии чисел, а затем разобрать эту строку, используя strtol в цикле и заботясь о конечном указателю уделяется strtol ,

Вам необходимо задокументировать формат ввода, по крайней мере, в виде комментариев. Для этого вы можете использовать нотацию EBNF, а затем использовать стандартные методы parsing.

Конечно, вы должны скомпилировать все предупреждения и информацию об отладке (например, gcc -Wall -Wextra -g при использовании GCC ...). Затем научитесь использовать отладчик (например, gdb). Это необходимый навык.

+0

Я прочитал документацию scanf и увидел разные возвращаемые значения, но я подумал, что после первого сбоя вы все равно можете перейти к другому scanf. возвращаемое значение scanf никогда не сбрасывается? – Val

+0

Вы можете продолжить, но после сбоя 'scanf' не потребляет вход. –

+0

это интересно! Спасибо вам за разъяснение! я попытаюсь использовать вход другим способом. благодаря! – Val

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