2010-02-25 14 views
11

Nella classe delle strutture dati che sto attualmente prendendo, ci è stato assegnato il compito di scrivere un web crawler in C++. Per darci un vantaggio, il professore ci ha fornito un programma per ottenere l'origine da un determinato URL e un semplice parser HTML per rimuovere i tag. La funzione principale per questo programma accetta argomenti e quindi usa argc/argv. Il codice utilizzato per controllare gli argomenti è il seguente:Perché controllare se (* argv == NULL)?

// Process the arguments 
if (!strcmp(option, "-h")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "-t")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "-a")) 
{ 
    // do stuff... 
} 

if (*argv == NULL) 
{ 
    exit(1); 
} 

Dove "bottone" è stato popolato con l'interruttore in argv [1], argv [2] e superiore ha i restanti argomenti. Il primo blocco lo capisco bene, se l'interruttore è uguale alla stringa fai tutto ciò che è basato sull'interruttore. Mi chiedo quale sia lo scopo dell'ultimo blocco if.

Potrebbe essere che il mio C++ sia un po 'arrugginito, ma mi sembra di ricordare * argv che è equivalente a argv [0], in pratica significa che sta verificando che gli argomenti esistano. Tranne che avevo l'impressione che argv [0] sempre (almeno nella maggior parte delle implementazioni) contenesse il nome del programma in esecuzione. Mi viene in mente che argv [0] potrebbe essere nullo se argc è uguale a 0, ma cercando su Google non sono riuscito a trovare un singolo post che determini se sia o meno possibile.

E così mi rivolgo a voi. Che cosa è esattamente quel finale se il controllo dei blocchi?

EDIT: Sono andato con la motivazione fornita nei commenti della risposta selezionata, che può essere possibile per provocare intenzionalmente argv [0] a diventare NULL, o altrimenti diventano NULL basata su una piattaforma specifica implementazione di main.

+3

Si noti che 'argv' non è un array, ma un puntatore. Ciò significa che puoi perfettamente dire "argv ++" per scorrere le opzioni. Non è necessario modificare il valore di * * argv'. –

+0

Per curiosità, quale è stata la ragione del tuo professore quando glielo hai chiesto? – Daniel

+0

Ora, 5 anni dopo, temo davvero di non ricordare. Mi sembra di ricordare vagamente di aver chiesto alla mia AT e il ragionamento è lo stesso dei commenti della risposta accettata (vedi la MODIFICA nella domanda), ma potrei fare questo e ricordare semplicemente tutto sbagliato. : P –

risposta

9

argc fornirà il numero di argomenti della riga di comando passati. Non dovresti avere bisogno di controllare il contenuto di argv e vedere se non ci sono abbastanza argomenti.

if (argc <= 1) { // The first arg will be the executable name 
    // print usage 
} 
+0

Lo so, il codice sopra riportato è il codice che ci è stato dato dal nostro professore. Personalmente, controllo sempre contro argc. Sto chiedendo cosa è * argv == NULL in realtà il controllo? La mia impressione è che è come controllare argv [0] == NULL, che per quanto ne so è impossibile, quindi perché controllarlo? –

+3

@Shaun: Sì, '* argv' è identico a' argv [0] '. Normalmente non è possibile quando si esegue l'app da una normale shell. Ma io * penso * potrebbe essere possibile se si esegue un processo direttamente da un altro programma usando la chiamata di sistema 'exec' e passando manualmente gli array. –

+0

Pensavo che argv [0] contenesse sempre il nome del programma, quindi, perché controllare se è NULL? –

4

Ricordando quanto sia portatile C, potrebbe non essere sempre in esecuzione su una piattaforma standard come Windows o Unix. Forse è un po 'di micro-codice all'interno della tua lavatrice che funziona su un ambiente economico e compromesso. Pertanto, è buona norma assicurarsi che un puntatore non sia nullo prima di dereferenziarlo, il che potrebbe aver portato alla domanda.

Anche così, sei corretto. * argv è lo stesso di argv [0] e argv è supposto da inizializzare dall'ambiente, se fornito.

+4

'Forse è un po' di micro-codice all'interno della lavatrice '- Fantastico, ora sto aspettando il messaggio "Scusa, devi aggiornare' Adobe Flash 'alla versione più recente per inserire il ciclo di risciacquo." –

+2

Blue Wash of Death: P – MSalters

10

3.6.1/2:

Se argc è diverso da zero tali argomenti sono forniti in argv [0] se ... e argv [0] sono il puntatore al carattere iniziale di un NTMBS che rappresenta il nome utilizzato per richiamare il programma o "". Il valore di argc deve essere non negativo. Il valore di argv[argc] sarà 0.

enfasi è mia. argc è garantito solo non negativo, non diverso da zero.

Questo è all'ingresso principale. È anche possibile che //do stuff modifichi il valore di argv o il contenuto dell'array a cui punta. Non è del tutto inaudito per il codice di gestione delle opzioni per spostare i valori fuori da argv mentre li elabora.Il test per *argv == null può quindi verificare se sono rimasti o meno argomenti della riga di comando, dopo che le opzioni sono state rimosse o ignorate. Dovresti guardare il resto del codice.

4

solo una speculazione.

e se il tuo professore si riferisce a questo?

while(*++argv !=NULL) 

    printf("%s\n",*argv);