2012-04-15 12 views
2

Wenn ich einen Benutzer einen Dateinamen für eine Datei eingeben lassen (Leerzeichen zulassen) und es überprüfen sollte, um zu sehen, ob es ein ungültiger Dateiname ist, wie würde ich das tun?Validieren der Benutzereingabe für Dateinamen

Der einzige Weg, gerade jetzt, dass ich denken kann, ist char-Array zu erstellen wie

char filename[100] 

Und eine for-Schleife verwenden und wenn Anweisungen verschachtelt, dass, wenn jedes einzelne Zeichen der Zeichenkette geprüft werden! @%^* ~ | und etc durch Schreiben Linien wie diese

for(...) { 
    if(filename[i] == '@'){...} 
    if(filename[i] == '!'){...} 
} 

Gibt es bessere Möglichkeiten, dies zu nähern? Denn wenn ich es so machen würde, hätte ich VIELE einzelne if-Anweisungen, um alle möglichen illegalen Charaktere zu testen.

Antwort

5

Sie können strchr dafür verwenden, und wenn die Rückgabe nicht null ist, haben Sie ein schlechtes Zeichen gefunden.

char bad_chars[] = "[email protected]%^*~|"; 
char invalid_found = FALSE; 
int i; 
for (i = 0; i < strlen(bad_chars); ++i) { 
    if (strchr(filename, bad_chars[i]) != NULL) { 
     invalid_found = TRUE; 
     break; 
    } 
} 
if (invalid_found) { 
    printf("Invalid file name"); 
} 
+0

Dies ist definitiv der schnellste Weg, weniger Raum für Fehler. –

+0

Vielen Dank, das ist eine sehr gute Lösung! –

+0

Dies ignoriert die leere Zeichenfolge. Es ist auch eine gute Methode, dies zu überprüfen. –

2

Sie könnten versuchen, regex:

#include <stdlib.h> 
#include <string.h> 
#include <regex.h> 

int main (void) { 
    char fileName[100]; 
    int comp; 
    regex_t myregex; 

    // Compile the regular expression 
    comp = regcomp(&myregex, "^[a-zA-Z0-9.' '\[\]_-]+$", REG_EXTENDED | REG_NOSUB) ; 

    printf("Enter a file name\n"); 
    scanf("%s",fileName) ; 

    // Compare fileName to the regex 
    if (!regexec(&myregex, fileName, 0 , 0 , 0)) { 
     printf("fileName %s is valid.\n", fileName); 
    } else { 
     printf("fileName %s is invalid.\n", fileName); 
    } 
    return 0; 
} 
+1

+1 Netter Ansatz. zwei Kommentare: 1. Es sollte beachtet werden, dass dies nur für POSIX ist. 2. 'regex_t * myregex; 'sollte sein' regex_t myregex; 'und dann' regcomp (& myregex, ... ' – MByD

+0

Danke, ich hätte meinen Code ein wenig besser kommentieren und sehen sollen. –

0

Diese vielleicht eine einzigartige Lösung (I genug Informationen nicht auf Ihre Anwendung haben, also werde ich es trotzdem schreiben), aber wenn Sie nur alphanumerische wollen Namen können Sie den ganzzahligen Wert einer Reihe von Zeichen vergleichen, die eine einfache (r) if-Anweisung wäre:

wenn Sie sehen möchten, wenn ihr ein Groß-/Kleinschreibung oder eine Zahl:

// pseudo wenn (0-9, a-z, A-Z) fortfahren;

sonst ablehnen; sowie

for(i=0;...;...){ 
    if((filename[i]==32)||(filename[i]>47 && filename[i]<58)||(filename[i]>64 && filename[i]<91)|| 
    (filename[i]>96 && filename[i]<123)) 
     continue; 
else{ 
...//reject filename 
} 

Alternativ können Sie, wenn sich eine nicht-alphanumerische sehen ...

for(i=0;...;...){ 
    if((filename[i]<=47) || (filename[i]<=64 && filename[i]>=58) || 
    (filename[i]<=96 && filename[i]<=91) || (filename[i]<=123)){ 
     reject; 
    else{ 
     ...//nothing 
    } 

http://www.asciitable.com/

+0

Wäre es nicht einfacher (und passender) zu schreiben:' ... filename [i]> = '0' && filename [i] <= '9' ... '? – MByD

+0

Nicht sicher, können Sie mehr Details darüber geben, was Sie unter" einfacher? einfacher auf den Augen? "verstehen Ich bin mir nicht sicher, was ein gültiger Name ist, deshalb ist es schwierig, einen klaren Vorschlag zu machen, aber anstatt zu versuchen, jeden ungültigen Charakter zu vergleichen, schlage ich vor, dass er sie in möglichst großen Gruppen zusammenfasst Ich bevorzuge es nicht> = zu verwenden, da dies in der Regel 2 Vergleiche statt einer ist Es macht es auf den ersten Blick weniger einfach zu verstehen –

+1

Ich habe kein Problem mit Ihrer Herangehensweise, ich meinte nur, dass es besser lesbar sein wird nicht irgendwelche magischen Zahlen :) – MByD