Funkcja fgets() nie wczytuje łańcucha po scanf() w języku C.

0

Znowu mam problem, którego nie potrafię zlokalizować. Nauczyliście mnie już czemu scanf() po scanf() nie wczytuje wartości, ale jak to jest z fgets() po scanf()? Program ma wczytywać N znaków z podanego tekstu i wyświetlać wczytany tekst, zamiast tego pokazuje się to co jest w drugiej i trzeciej funkcji scanf(), nic więcej. Bardzo proszę o pomoc, padam już od tego. Jeżeli ktoś rozwiąże ten problem to prosiłbym o źródła z jakich nauczyliście się rozwiązywać takie problemy.

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

int main(void)
{
    char tekst[256];
    int liczba;
    
    printf("Podaj liczbe N znakow ktore maja byc odczytane: ");
    scanf("%d", &liczba);
    printf("\n\nA teraz wprowadz do 255 znakow:\n");
    fgets(tekst, liczba, stdin);
    printf("Wprowadzono nastepujacy teskt:\n");
    fputs(tekst, stdout);
    getch();
    return 0;
}
1

Jak nikt nie wie to ja powiem bo sam się dobiłem do rozwiązania tego problemu. Wystarczy dać getchar() po pierwszej funkcji scanf().

#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
int main(void)
{
    char tekst[256];
    int liczba;
 
    printf("Podaj liczbe N znakow ktore maja byc odczytane: ");
    scanf("%d", &liczba);
    getchar();
    printf("\n\nA teraz wprowadz do 255 znakow:\n");
    fgets(tekst, liczba, stdin);
    printf("Wprowadzono nastepujacy teskt:\n");
    fputs(tekst, stdout);
    getch();
    return 0;
}
2

problem jest taki ze po scanf musisz zrobić flush na buforze stdin, wywołanie tej drugiej funkcji sprawiło że ci sie udało wyczyścić bufor stdin, nie jest to jednak w pełni poprawna metoda.
Co powoduje takie dziwne działanie? Przykładowo wpisałeś a b c d <enter> w buforze pojawiło się :
a b c d \n
po wywołaniu scanf zostaja odczytane z bufora znaki:
a b c d
natomiast w buforze jest \n (znak końca linii), jeżeli teraz użyjesz fgets który odczytuje wszystko do znaku końca linii odczytasz tylko "\n" - pusta linię.
getchar usunęło znak \n i dla tego fgets zadziałał prawidłowo.
Jak widać problemem są śmieci pozostałe w buforze po scanf, można się natknąć na metodę czyszczenia bufora poprzez funkcje fflush:
fflush(stdin) jest to jedna metoda której tym bardziej trzeba unikać ponieważ działa na większości PC nie na wszystkich. Innym popularnym rozwiązaniem jest:
while((c = getchar()) != '\n' && c != EOF);
Która działa na podobnej zasadzie jak twoja z tym ze usuwa wszystkie smieci jakie mogły pozostać po scanf.
Na internecie znajdziesz jeszcze kilka innych np. metod http://www.daniweb.com/software-development/c/code/217396/how-to-properly-flush-the-input-stream-stdin
Jaka jest najlepsza? NIE UŻYWAĆ SCANF, jezeli już musisz uzyć scanf skorzystaj z sscanf http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/

0

Studiuję teraz tą funkcję sscanf(). Z tego, co rozumiem, to ona pobiera z łańcucha dane określone przez specyfikatory konwersji. Z tego wynika, że w łańcuchu tym muszą wcześniej się znaleźć dane, czyli jestem zdany tylko na scanf(), skoro chcę wprowadzić dane liczbowe. Poza tym dzięki za linki i za wytłumaczenie, zastanawia mnie czy jest w Polsce dobra książka o C :( .

0

Czyli gdybym przerobił "Język ANSI C. Progrmowanie. Wydanie II" zamiast tej całej "...Szkoły Programowania" to nie zadawałbym takich pytań jak w tym temacie? Jak przerobie szkołę programowania to na pewno kupię tą pierwszą. Na razie muszę mieć to lanie wody, które jest potrzebne dla początkującego.

1

Szczerze mówiąc, jeszcze nie spotkałem się z książką lepszą dla początkujących niż Biblia K&R. Czy byś nie zadawał takich pytań to nie wiem. Zależy od tego jak dobrze przyswajasz wiedzę, czy wykonasz ćwiczenia tam zawarte, czy włożysz nieco wysiłku w przestudiowanie dokumentacji itp. "Język ANSI C" opisuje wszystko co jest potrzebne do rozpoczęcia programowania w C. Reszta to już wykorzystanie tej wiedzy do pisania kodu.
Język C sam w sobie jest banalnie prosty. Opiera się na prostych zasadach i kilku kruczkach, o których trzeba pamiętać. Złożone jest wykorzystywanie go do tworzenia oprogramowania, gdyż wielu rzeczy standardowych w innych językach tutaj nie ma i trzeba je zaimplementować samemu (lub skorzystać z zewnętrznych bibliotek). Nieuważne i/lub nieumiejętne pisanie kodu w C może prowadzić do błędów, które mogą objawić się późno (np. kiedy wszyscy będą przekonani, że kod jest poprawny), a nawet do poważnych luk w bezpieczeństwie. To jest najtrudniejszym elementem programowania w C. Sam język jest prosty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1