Il più semplice "corretto" modo è probabilmente questa, presa dalla carta di Bjarne Stroustrup Learning Standard C++ As A New Language.
(Nota: ho cambiato il codice di Bjarne per verificare isspace()
invece che solo alla fine della riga Inoltre, a causa di @ matejkramny commento, da usare al posto di while(1)
while(true)
... e fino a quando ci stanno abbastanza eretica. di modificare il codice di Stroustrup, ho subbed in C89 commenti invece di C++ stile troppo :-P)
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
void quit() /* write error message and quit */
{
fprintf(stderr, "memory exhausted\n");
exit(1);
}
int main()
{
int max = 20;
char* name = (char*) malloc(max); /* allocate buffer */
if (name == 0) quit();
printf("Enter a file name: ");
while (1) { /* skip leading whitespace */
int c = getchar();
if (c == EOF) break; /* end of file */
if (!isspace(c)) {
ungetc(c, stdin);
break;
}
}
int i = 0;
while (1) {
int c = getchar();
if (isspace(c) || c == EOF) { /* at end, add terminating zero */
name[i] = 0;
break;
}
name[i] = c;
if (i == max - 1) { /* buffer full */
max += max;
name = (char*) realloc(name, max); /* get a new and larger buffer */
if (name == 0) quit();
}
i++;
}
printf("The filename is %s\n", name);
free(filename); /* release memory */
return 0;
}
che copre:.
- saltare gli spazi fino a raggiungere carattere mettere
- espandere il buffer di stringa in modo dinamico per soddisfare le stringhe di dimensioni arbitrarie
- condizioni di manipolazione di quando la memoria non può essere allocato
Ci sono soluzioni più semplici, ma rotti, che potrebbe anche correre un po 'più veloce? Assolutamente!!
Se si utilizza scanf in un buffer senza limite per le dimensioni di lettura, l'input supera la dimensione del buffer, creerà un buco di sicurezza e/o un arresto anomalo.
Limitare la dimensione della lettura a, diciamo, solo 100 caratteri univoci di un nome di file potrebbero sembrare migliori di crash. Ma può essere peggio; ad esempio se l'utente intendeva (...)/dir/foo/bar.txt
ma si finisce per erroneamente interpretare il proprio input e sovrascrivere un file chiamato bar.t
che forse gli importava.
È meglio entrare presto in buone abitudini nell'affrontare questi problemi. La mia opinione è che se le vostre esigenze giustificano qualcosa di vicino al metallo e "C-like", vale la pena considerare il passaggio al C++. È stato progettato per gestire con precisione queste preoccupazioni - con tecniche robuste ed estendibili, ma con buone prestazioni.
Eventuali duplicati http://stackoverflow.com/questions/314401/how-to-read-a-line-from-the-console-in-c –