Rumburak napisał(a)
Nie można się nie zgodzić z uwagami, ale zamieszczony przez Ciebie kod wywala się jak nie wpiszę żadnego znaku i potwierdzę enterem
Co rozumiesz przez "wywala się"? U mnie wypisuje komunikat błędu, tak jak powinien.
Rumburak napisał(a)
(kompiluje w QT pod windowsem - jeżeli ma to jakieś znaczenie?). :/
Qt to jest framework, nie kompilator. System operacyjny nie powinien mieć tu znaczenia.
Rumburak napisał(a)
Poza tym, to co napisałeś to bardzo czarna magia. Nic nie rozumiem, nawet nie wiem o co dopytywać :)
OK, to teraz z tłumaczeniem:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Includy... najwyraźniej
int main(void)
{
long int value, max = 0;
char *endptr, input[128];
int i;
Deklaracje. Zmienna value
przechowuje skonwertowaną wartość, max
- maksymalną wartość, pod endptr
funkcja strtol()
zapisze wskaźnik do miejsca, na którym kończy się konwersja, input
to nasz bufor (można go zmniejszyć, bo 128 bajtów to trochę przydużo), zaś i
posłuży nam do iteracji. Zmienną max
od razu inicjujemy wartością 0. Jeśli dopuszczamy wartości ujemne, powinniśmy ją zainicjować najmniejszą wartością, jaką na danej platformie jest w stanie przechować typ long int
.
errno = 0;
endptr = input;
Najpierw zerujemy zmienną globalną errno
. Teoretycznie nie jest to wymagane, gdyż nigdzie przed tą linią nie wywołujemy nic co mogłoby ją ustawić, ale nie zaszkodzi. Linia endptr = input
jest tu niepotrzebna (sorry, część kodu skopiowałem z mojego innego programu i zostały śmieci).
for ( i = 0; i < 10; i++ ) {
if ( fgets(input, sizeof(input) - 1, stdin) == NULL ) {
break; /* Ctrl-D przerywa wprowadzanie danych wcześniej */
};
Wchodzimy do pętli for
, która zrobi 10 obrotów. Przy każdej iteracji wczytujemy z stdin lnię tekstu, o długości równej maksymalnej objętości naszego bufora (i ponownie został śmieć; - 1
jest tutaj niepotrzebny, ale nie wadzi). Jeśli user nie wpisze nic, lecz wdusi kombinację Ctrl-D (fgets() zwróci NULL), iterowanie zostanie przerwane. Uwaga! Wpisanie pustej linii (wciśnięcie ENTER) nie łapie się do tego warunku, gdyż w danych wejściowych będzie znak nowej linii.
value = strtol(input, &endptr, 10);
Przeprowadzamy konwersję ze cstringa input
, podstawa 10. Wynik ląduje w zmiennej value
. Wskaźnik endptr
będzie wskazywał pierwszą pozycję z input
, na której znajduje się bajt nie należący do wartości liczbowej. Np. jeśli spróbujemy skonwertować "123abc"
, wartością zwróconą będzie liczba 123, zaś endptr
będzie wskazywał na a
. Zaraz wykorzystamy to do kontroli błędów.
if ( input == endptr || ((*endptr != '\n') && (*endptr != '\0')) ) {
fprintf(stderr, "Invalid input: %s\n", input);
return 2;
Jeśli wskaźnik endptr
wskazuje na pierwszy bajt danych wejściowych (input == endptr
), to znaczy że cstring rozpoczyna się od danych, których nie można przekonwertować na liczbę. Jeśli wskaźnik endptr
nie wskazuje ani na znak nowej linii, ani na bajt zerowy, to znaczy że w cstringu po liczbie znajdują się jakieś inne znaki. Wszystkie te przypadki traktujemy jako błąd, gdyż nie są to prawidłowe dane wejściowe. Przykłady takich przypadków:
"abcd\n\0"
"123abcd\n\0"
"123 \n\0"
"\n\0"
} else if ( errno != 0 ) {
fprintf(stderr, "Value error: %s\n", strerror(errno));
return 3;
};
Jeśli konwersja nie może być przeprowadzona z innego powodu (np. przekroczenie zakresu), barfujemy i kończymy pracę.
if ( value > max )
max = value;
};
Sprawdzamy, czy odczytana wartość jest większa od zapamiętanej wartości maksymalnej i jeśli jest to prawda, zapisujemy ją jako największą.
fprintf(stdout, "Max: %li\n", max);
return 0;
}
Po wyjściu z pętli printujemy wynik i kończymy pracę bez błędu.