2015-04-05 3 views
0

Я пишу кусок кода в C, который выполняет итерацию T раз и каждый раз берет в качестве ввода текст небольшой песни, на которой он будет выполнять некоторую операцию подсчета (считая длину каждого слово). Пока я просто проверяю, работает ли вход, а это не так.C программа для чтения и хранения строк

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

#define MAX_SONG_SIZE 501 

int main(void){ 
    int T; 
    scanf("%d", &T); 
    while(T--){ 
     char* song = malloc(MAX_SONG_SIZE); 
     if(song == NULL){ 
      printf("malloc failed"); 
      return 1; 
     } 
     fgets(song, MAX_SONG_SIZE, stdin); 
     printf("foo\n"); 
     free(song); 
    } 
    return 0; 
} 

Я использую fgets() из-за пробелов между словами, и динамическое выделение памяти, потому что я не могу просто использовать один массив для всех песен, персонажи из предыдущей итерации будет оставаться в массив.

Но есть проблема. Он пропускает fgets() в первой итерации, записывая только «foo» и не дожидаясь, когда я вставлю строку.

Это пример того, как он печатает с начальным входом "3":
Foo
это тест
Foo
другой тест
Foo


С заменяя printf("foo\n"); на printf("<<%s>>\n", song);, выход:

3<br> 
<< <br> 
>> <br> 
test <br> 
<<test <br> 
>> <br> 
another test <br> 
<<another test <br> 
>> <br> 

Как я могу решить эту проблему? Если у вас есть ANY совет приветствуется.

+2

новой строки после 3 остается в буфере в ожидании первых 'fgets()', чтобы прочитать его. Перед запуском вызовов на 'fgets()' вам нужно прочитать до конца первой строки, номер с номером на ней. Например: 'int c; while ((c = getchar())! = EOF && c! = '\ n'); 'будет работать нормально. Вы должны проверить возвращаемое значение из 'fgets()' тоже, если вы столкнулись с EOF до того, как T-строки были прочитаны. В конце концов, вы избавитесь от T и просто попросите компьютер подсчитать строки - компьютеры хороши в подсчете. Вы можете отладить это с помощью печати: 'printf (" <<%s>> \ n ", песня);' поможет. –

+0

Обратите внимание, что вы можете использовать статически выделенный буфер, поскольку вы передаете фиксированный размер в 'malloc' в любом случае. – Diego

+0

@JonathanLeffler: Я добавил в главный пост, как он печатает с вашим отладочным трюком – Ice

ответ

3

Там в \n осталось во входном буфере, см http://c-faq.com/stdio/scanfinterlace.html

цитата из ссылки:

Как правило, вы не должны пытаться чередовании вызовы Scanf с вызовами gets() (или любые другие процедуры ввода); Счастье scanf Обработка новых строк почти всегда приводит к проблемам. Либо используйте scanf , чтобы прочитать все или ничего.

+0

Да, это проблема, хотя я не использовал scanf. – Ice

+1

@ Когда вы делали 'scanf ("% d ", &T);'? –

+0

Да, я не думал, что это важно в этом int. – Ice

0

Во входном буфере слева находится \ n. Одно решение состоит в:

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

#define MAX_SONG_SIZE 501 

int main(void){ 
    int t; 
    scanf("%d", &t); 
    getchar(); 

    char song[MAX_SONG_SIZE]; 
    while(t--){ 
     fgets(song, MAX_SONG_SIZE * sizeof(char), stdin); 
     printf("foo\n"); 
    } 
    return 0; 
} 

Смотрите также: How to clear input buffer in C?

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