2013-02-14 31 views
6

Ho cercato di utilizzare espressioni regolari su scanf, per leggere una stringa di massimo n caratteri e scartare qualsiasi altra cosa fino al carattere New Line. Tutti gli spazi devono essere trattati come caratteri regolari, quindi inclusi nella stringa da leggere. Ho studiato un articolo su Wikipedia sulle espressioni regolari, ma non riesco a far funzionare correttamente scanf. Ecco il codice che ho provato:Utilizzare scanf con le espressioni regolari

scanf("[ ]*%ns[ ]*[\n]", string); 

[] si suppone di andare per il carattere di spazio effettivo, * dovrebbe significare uno o più, n è il numero di caratteri da leggere e la stringa è un puntatore assegnato con malloc. Ho provato diverse combinazioni; tuttavia tendo ad ottenere solo la prima parola di una frase letta (si ferma al carattere dello spazio). Inoltre, * sembra scartare un carattere invece di indicare "zero o più" ...

Qualcuno potrebbe spiegare in dettaglio in che modo le espressioni regolari vengono interpretate da scanf? Inoltre, è efficiente utilizzare getc ripetitivamente?

Grazie in anticipo: D

+2

Prova 'fgets()': 'fgets (stringa, sizeof stringa, stdin);' – pmg

+0

Il problema è che tutti i caratteri rimanenti saranno lasciati nello stream di input, vero? – someone

+0

Se c'è spazio sufficiente 'fgets()' consuma tutto fino a (e includendo) un ''\ n''. – pmg

risposta

4

La risposta breve: scanf non gestisce le espressioni regolari letteralmente parlando.

Se si desidera utilizzare le espressioni regolari in C, è possibile utilizzare la libreria POSIX regex. Vedere la seguente questione un esempio di base su questo utilizzo libreria: Regular expressions in C: examples?

Ora, se si vuole farlo nel modo scanf si potrebbe provare qualcosa di simile

scanf("%*[ ]%ns%*[ ]\n",str); 

Sostituire il n nel %ns per il numero massimo di caratteri da leggere dallo stream di input. La parte %*[ ] chiede di ignorare qualsiasi spazio. È possibile sostituire lo * con un numero specifico per ignorare un numero preciso di caratteri. È possibile aggiungere altri caratteri tra parentesi per ignorare più di semplici spazi.

Non sono sicuro se la scansione precedente funzionerebbe come gli spazi sono anche abbinati alla direttiva %s.
avrei sicuramente andare con una chiamata fgets, quindi triming i spazi bianchi circostanti con qualcosa come il seguente: How do I trim leading/trailing whitespace in a standard way?

+0

Quindi, dopo tutto, non c'è altro modo per scartare qualsiasi input rimanenti? Ho pensato di usare getc ripetutamente, mantenendo il numero di caratteri di cui ho bisogno e scartando il resto della stringa fino a trovare il carattere \ n ... – someone

+0

Ho modificato la mia risposta nello stesso momento in cui hai postato il tuo commento. Quindi sì, è possibile ignorare qualche input, ma non chiamerei la stringa di formato scanf una "espressione regolare". – greydet

+0

Grazie per la tua risposta! Tuttavia, puoi spiegare la semantica di ciò che hai usato lì? – someone

2

è efficiente utilizzare getc ripetutamente invece?

Dipende piuttosto sull'applicazione, ma YES, ripetuto getc() è efficiente.

0

a meno che non abbia letto la domanda errata,% [^ '\ n'] s salverà tutto fino a quando non viene rilevato il ritorno a capo.

+1

Il 's' in'% [^ '\ n'] s' non è necessario. – chux