Sto scrivendo un programma per scrivere rapidamente i miei file html. E quando sono venuto a scrivere il contenuto della mia pagina ho avuto un problema.
#include int main() { int track; int question_no; printf("\nHow many questions?\t"); scanf("%d",&question_no); char question[question_no][100]; for(track=1;track<=question_no;track++) { printf("\n%d. ",track); printf("\nQuestion number %d.\t",track); fgets(question[track-1],sizeof(question[track-1]),stdin); printf("\n\n\tQ%d. %s ",track,question[track-1]); } }
In questo programma sto scrivendo alcune domande e le loro risposte (nel file html). Quando eseguo il test di questo programma, inserisco il valore di question_no
in 3. Ma quando inserisco la mia prima domanda non va in question[0]
e di conseguenza la prima domanda non viene emessa. Il resto delle domande è stato inserito senza problemi.
Ho cercato alcune domande su StackOverflow e ho scoperto che fgets()
cerca l’ultimo carattere \0
e che \0
interrompe.
Ho anche scoperto che dovrei usare il buffer per inserire bene attraverso fgets()
quindi ho usato: setvbuf
e setbuf
ma anche questo non ha funzionato (potrei averlo scritto male). Ho anche usato fflush(stdin)
dopo la mia prima e ultima (anche) istruzione scanf
per rimuovere qualsiasi carattere \0
dallo stdin ma che non ha funzionato.
C’è un modo per accettare il primo input di fgets()
?
Sto usando stdin e stdout per ora. Non sto accedendo, leggendo o scrivendo alcun file.
Usa anche i comandi per il primo prompt. Dovresti anche malloc
tuo array perché non sai quanto tempo sarà in fase di compilazione.
#include #include #define BUFSIZE 8 int main() { int track, i; int question_no; char buffer[BUFSIZE], **question; printf("\nHow many questions?\t"); fgets(buffer, BUFSIZE, stdin); question_no = strtol(buffer, NULL, 10); question = malloc(question_no * sizeof (char*)); if (question == NULL) { return EXIT_FAILURE; } for (i = 0; i < question_no; ++i) { question[i] = malloc(100 * sizeof (char)); if (question[i] == NULL) { return EXIT_FAILURE; } } for(track=1;track<=question_no;track++) { printf("\n%d. ",track); printf("\nQuestion number %d.\t",track); fgets(question[track-1],100,stdin); printf("\n\n\tQ%d. %s ",track,question[track-1]); } for (i = 0; i < question_no; ++i) free(question[i]); free(question); return EXIT_SUCCESS; }
Una matrice di type
2D può essere rappresentata da una serie di puntatori da type
o di type**
equivalente type**
(puntatore al puntatore al type
). Ciò richiede due passaggi.
Utilizzando la char **question
come esempio:
Il primo passo è allocare un array di char*
. malloc
restituisce un puntatore all'inizio della memoria che ha allocato, oppure NULL
se ha fallito. Quindi controlla se la question
è NULL
.
La seconda è di rendere ognuno di questi punti char*
al proprio array di char
. Quindi il ciclo for
alloca un array della dimensione di 100 char
per ogni elemento della question
. Ancora, ognuno di questi malloc
potrebbe restituire NULL
quindi è necessario verificarlo.
Ogni malloc
merita un free
quindi è necessario eseguire il processo in senso inverso quando hai finito di usare la memoria che hai assegnato.
riferimento malloc
long int strtol(const char *str, char **endptr, int base);
strtol
restituisce un long int
(che nel codice sopra è castato in un int
). Si divide in tre parti:
Se endptr
non è NULL
, punta alla terza parte, quindi sai dove finisce lo strtol
. Potresti usarlo in questo modo:
#include #include int main() { char * endptr = NULL, *str = " 123some more stuff"; int number = strtol(str, &endptr, 10); printf("number interpreted as %d\n" "rest of string: %s\n", number, endptr); return EXIT_SUCCESS; }
produzione:
number interpreted as 123 rest of string: some more stuff
riferimento strtol
Questo perché il carattere di nuova riga precedente è rimasto nel stream di input di scanf (). Nota che fgets () si ferma se incontra anche una nuova riga.
fgets () legge al massimo un carattere in meno rispetto alla dimensione dal stream e li memorizza nel buffer indicato da s. La lettura si interrompe dopo un EOF o una nuova riga. Se una nuova riga viene letta, viene archiviata nel buffer
Non mischiare fgets () e scanf (). Una soluzione banale è usare getchar () subito dopo scanf () per consumare la nuova riga a sinistra nel stream di input di scanf ().
Secondo la documentazione ,
La funzione fgets () legge i byte dallo stream nell’array puntato da s, finché i byte n-1 non vengono letti, oppure un
viene letto e trasferito a s, oppure si verifica una condizione di fine file
In caso di scanf("%d",&question_no);
una nuova riga è lasciata nel buffer e viene letta da
fgets(question[track-1],sizeof(question[track-1]),stdin);
e esce.
Per scaricare il buffer dovresti farlo,
while((c = getchar()) != '\n' && c != EOF) /* discard */ ;
per cancellare i caratteri extra nel buffer