2012-04-15 2 views
0

Моя задача считывается двумя строками цифр и сохраняет их в разных массивах. Я решил использовать функцию scanf, но программа может читать только первую строку. Это мой плохой код.Scanf и две строки

int main() 
{ 

    int firstArray[50], secondArray[50], i, j; 

    /* fill an array with 0 */ 
    for(i=0; i<50; ++i) 
    { 
     firstArray[i]=secondArray[i]=0; 
    } 

    i=j=0; 

    while((scanf("%d", &firstArray[i]))== 1) { ++i; } 
    while((scanf("%d", &secondArray[j]))== 1) { ++j; } 

    /* Print this. */ 
    for(i = 0; i < 20; ++i) 
    { 
     printf("%d ", firstArray[i]); 
    } 
    putchar('\n'); 

    for(j = 0; j < 20; ++j) 
    { 
     printf("%d ", secondArray[j]); 
    } 

    return 0; 
} 

Я просто не понимаю, как работает функция scanf. Может кто-нибудь объяснить?

+0

Как выглядит вход в 'scanf'? –

+0

# первая строка 123 54 34 54 3455 [конец строки; или \ n]. И # вторая строка - то же самое/ – Ascelhem

+0

@ user1334306 читать этот комментарий только сейчас, собираюсь обновить мой ответ! – ShinTakezou

ответ

0

Вы не можете использовать scanf для этого.

Прочитать documentation.

Наблюдения:

  1. с scanf, если ввести цифру ваш цикл работает вечно
  2. нет никакой проверки на размер 50 предел ваших массивов
  3. если нажать return то он игнорирует эту линию, потому что не соответствует вашему шаблону
  4. , если вы введете письмо, образец не соответствует, и разрывы цикла

Поэтому используйте некоторые другие функции, возможно gets, atoi или strtol. И не забудьте проверить размер 50 ваших массивов.

+0

scanf не будет работать вечно, если номер введен, он будет читать это число, и если следующее чтение не является числом или пробелом, пропустите цикл while. Письмо не приведет к исключению. Он просто не будет читаться, и оба цикла будут завершены. – Morpfh

+0

Если это не номер, у вас есть ошибка, если вы введете пробел, он пропустит эту строку и продолжит цикл. Попробуй. – dash1e

+0

Если это * не число * или * не пустое, оно прерывает цикл while. Если это не номер, это будет *** не *** ошибка. Он проверяет, имеет ли scanf 1 прочитанный элемент. Поэтому, если есть непустой или не номер, scanf вернет 0 и разрыв цикла while. Не исключение или ошибка. – Morpfh

0

scanf игнорирует пустые символы (включая новую строку). Таким образом, ваше сканирование будет считывать весь ввод в firstArray, если у вас нет разделителя «non blank».

Если файл/данные имеют ; в конце первой строки это не остановит чтение в firstArray там, и никогда не читал что-нибудь в secondArray - как вы никогда не потребляете ;.

/* This will never be 1 as ; is blocking */ 
while((scanf("%d", &secondArray[i])) == 1) { 

Итак: если вы разделите с т ; вы должны прочитать/проверить это, прежде чем читать в secondArray.

Можно также добавить что-то вроде:

char c; 

/* this can be done more tidy, but only as concept */ 
while((scanf("%d", &firstArray[i])) == 1 && i < max) { 
    ++i; 
    if ((c = getchar()) == '\n' || c == ';') 
     break; 
} 

Также вместо инициализации массива в 0 петли вы можете сказать:

int firstArray[50] = {0}; /* This set every item to 0 */ 

принять Также уведомление, чтобы вы не идете над 50 предел.

0

На самом деле, есть одна специальная точка в массивах C.

Хотя вы объявляете размер массива. скажем int arr[5]; Вы можете хранить значения, превышающие размер . Он не показывает никаких ошибок, но приводит к неопределенному поведению (может перезаписать другие переменные).

Пожалуйста, обратитесь на этот вопрос: Array size less than the no. of elements stored in it

В вас случае, это ваша проблема. Компилятор никогда не выходил за рамки первых заявлений. Таким образом, вы не получили никакой информации. На самом деле, он даже не скомпилировал весь код!

while((scanf("%d", &firstArray[i]))== 1) { ++i; }

Таким образом, вы могли бы написать это время заявление, как это:

while( scanf("%d", &firstArray[i]) ==1 && i<50) 
    i++; 

или еще:

while(i<50) 
{ 
     scanf("%d", &firstArray[i]);    
     i++; 
} 

или еще:

for (i=0; i<50; i++) 
    scanf("%d", &firstArray[i]); 
+0

Ваши примеры неверны. Вы сравниваете указатель массива с '1'. Далее вы увеличиваете 'i', даже если номер не читается. И ваш второй и третий пример никогда не ломается, если читать элементы '! = 1'. – Morpfh

+0

@Rune Взгляните на них сейчас! На самом деле, я просто скопировал из того, что он написал, и забыл удалить их. – Surya

+0

Лучше, но на двух последних примерах вы не проверяете чтение, и поскольку шаблон не изменяется, если есть что-то еще, то пустое (пробел, newline), вы продолжаете пытаться читать, но никогда не становитесь дальше. I.Е если у вас есть вход '1 4 8; 3 6 5' вы прочитаете 1,4 и 8 в firstArray [0], [1] и [2] - затем попробуйте прочитать следующее число до тех пор, пока i не будет 50, но в качестве следующего символа ';' вы никогда не будете авансовый. – Morpfh

0

Вы говорите стри ngs цифр, и вы читаете %d. Формат сканирует вход для самой длинной последовательности, представляющей целочисленное (подписанное) значение. Две «разрядные строки» потребляются первым циклом while.

EDIT Вместо «строк цифр» вы должны указать «строки целых чисел». В этом случае он немного более тонкий, поскольку первый может потреблять все целые числа, если они не разделены чем-то, что не возможное целое число (например, ;).

Итак, чтобы сделать следующее, вы должны разделить две «линии» на то, что не может быть проанализировано как целое число и, которое не считается «белым символом». Не лучшее решение, но одно возможное.

#include <stdio.h> 
#include <ctype.h> 

int main() 
{ 

    int firstArray[50] = {0}; 
    int secondArray[50] = {0}; 
    int i, j, l1, l2; 
    int tmp; 

    i = j = 0; 

    // read integers, but not more than size of array 
    while(scanf("%d", &firstArray[i]) == 1 && i < sizeof(firstArray)) { 
    ++i; 
    } 

    // consume non digits 
    for(tmp = getchar(); tmp != EOF && !isdigit(tmp); tmp = getchar()); 
    // on EOF you should exit and stop processing; 
    // we read one more char, push it back if it was a digit 
    if (isdigit(tmp)) ungetc(tmp, stdin); 

    while(scanf("%d", &secondArray[j]) == 1 && j < sizeof(secondArray)) { 
    ++j; 
    } 

    l1 = i; // preserve how many ints were read 
    l2 = j; 

/* Print this. */ 
    for(i = 0; i < l1; ++i) 
    { 
    printf("%d ", firstArray[i]); 
    } 
    putchar('\n'); 

    for(j=0; j < l2; ++j) 
    { 
    printf("%d ", secondArray[j]); 
    } 

    return 0; 
} 

EDIT Решение, которое, возможно, подходит вашим потребностям лучше читать строки (один за раз) в буфер и sscanf буфера.