2010-07-09 29 views
36

In questo momento sto cercando questo:Come eseguire iterazioni su una stringa in C?

#include <stdio.h> 

int main(int argc, char *argv[]) { 

    if (argc != 3) { 

     printf("Usage: %s %s sourcecode input", argv[0], argv[1]); 
    } 
    else { 
     char source[] = "This is an example."; 
     int i; 

     for (i = 0; i < sizeof(source); i++) { 

      printf("%c", source[i]); 
     } 
    } 

    getchar(); 

    return 0; 
} 

Ciò, inoltre, non funziona:

char *source = "This is an example."; 
int i; 

for (i = 0; i < strlen(source); i++){ 

    printf("%c", source[i]); 
} 

ottengo l'errore

eccezione non gestita in 0x5bf714cf (msvcr100d.dll) in Test.exe: 0xC0000005: violazione di accesso durante la lettura nella posizione 0x00000054.

(liberamente tradotto dal tedesco)

Allora, cosa c'è di sbagliato con il mio codice?

+3

Si prega di non modificare il codice che hai chiesto. Questo cambia la tua domanda un po 'così che molte delle risposte sono irrilevanti. Invece, pubblica solo tutte le cose che hai provato e menziona quali di esse sono state in risposta alle risposte. –

+0

Il nuovo test contro l'argc che hai aggiunto è sbagliato. –

risposta

41

desiderato:

for (i = 0; i < strlen(source); i++){ 

sizeof ti dà la dimensione del puntatore, non è la stringa. Tuttavia, avrebbe funzionato se si fosse dichiarato il puntatore come un array:

char source[] = "This is an example."; 

ma se si passa la matrice a funzionare, anche questo decadrà a un puntatore. Per le stringhe è meglio usare sempre strlen. E nota cosa hanno detto altri riguardo al cambio di printf da usare% c. E anche, prendendo mmyers commenti sull'efficienza in considerazione, sarebbe meglio spostare la chiamata a strlen fuori dal giro:

int len = strlen(source); 
for (i = 0; i < len; i++){ 

o riscrivere il ciclo:

for (i = 0; source[i] != 0; i++){ 
+2

Uh, dubito che voglia usare 'strlen' come limite. (Sebbene concesso, in un programma a 10 linee non fa molta differenza.) –

+1

@mmyers Um, perché no? –

+9

Bene, l'ultima volta che ho controllato, strlen ha dovuto scorrere tutti i personaggi per capire la lunghezza. E poiché il char * potrebbe cambiare nel loop, la strlen non può essere issata fuori dai limiti controllati dal compilatore; ciò rende il ciclo O (n^2) invece di O (n). Per favore correggimi se sbaglio. –

0

Basta modificare sizeof con strlen.

Ti piace questa:

char *source = "This is an example."; 
int i; 

for (i = 0; i < strlen(source); i++){ 

    printf("%c", source[i]); 

} 
+0

questo codice avrà ancora un'eccezione a causa di% se il char è passato a printf – ULysses

+0

Grazie per averlo indicato. –

2

sizeof(source) restituisce il numero di byte richiesti dal puntatore char*. Dovresti sostituirlo con strlen(source), che sarà la lunghezza della stringa che stai tentando di visualizzare.

Inoltre, dovresti probabilmente sostituire printf("%s",source[i]) con printf("%c",source[i]) poiché stai visualizzando un personaggio.

+0

quindi ... probabilmente 'printf ("% c ", source [i])' con 'putchar (source [i])' ... – ShinTakezou

0

Sostituire sizeof con strlen e dovrebbe funzionare.

0

È necessario un puntatore al primo carattere per avere una stringa ANSI.

printf("%s", source + i); 

farà il lavoro

In più, naturalmente si dovrebbe avere significato strlen(source), non sizeof(source).

1

Questo dovrebbe funzionare

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]){ 

    char *source = "This is an example."; 
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation 
    for (int i = 0; i < length; i++) 
    { 

     printf("%c", source[i]); 

    } 


} 
1
  • sizeof(source) sta tornando a voi le dimensioni di un char*, non la lunghezza della stringa.Dovresti utilizzare strlen(source) e dovresti spostarlo fuori dal ciclo, altrimenti dovrai ricalcolare la dimensione della stringa ogni ciclo.
  • Stampando con il modificatore di formato %s, printf sta cercando un char*, ma in realtà stai passando un char. Dovresti usare il modificatore %c.
2
  1. sizeof() include il carattere nullo di terminazione. Dovresti usare strlen() (ma mettere la chiamata fuori dal ciclo e salvarla in una variabile), ma probabilmente non è ciò che sta causando l'eccezione.
  2. si dovrebbe usare "% c", non "% s" in printf - si stampa un carattere, non una stringa.
31

Un linguaggio comune è:

char* c = source; 
while (*c) putchar(*c++); 

Alcune note:

  • In C, le stringhe sono null-terminated. Si esegue iterazione mentre il carattere letto non è il carattere null.
  • *c++ incrementi c e restituisce il valore datato vecchio c.
  • printf("%s") stampa una stringa con terminazione null, non un carattere. Questa è la causa della violazione di accesso.
+1

Posso usare 'while (* C++) putc (* c);' ? –

+0

-1 "In C, le stringhe sono terminate da zero." Questo non ha senso. Forse quello che stai cercando di dire è che le stringhe di c devono essere terminate con null. – Celeritas

+3

@Celeritas: Trovo il downvote un po 'duro - C ha il supporto del linguaggio per stringhe a terminazione zero, e l'OP sta usando quelli. Certo, è possibile utilizzare le stringhe conteggiate (ad esempio 'BSTR's nel mondo Windows), ma sono meno comuni e la domanda non è ambigua su quale tipo di stringa si stia utilizzando. –

2

Piuttosto che utilizzare strlen come suggerito sopra, si può solo controllare il carattere NULL:

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    const char *const pszSource = "This is an example."; 
    const char *pszChar = pszSource; 

    while (pszChar != NULL && *pszChar != '\0') 
    { 
     printf("%s", *pszChar); 
     ++pszChar; 
    } 

    getchar(); 

    return 0; 
} 
+1

Funzionerà, ma raccomanderei comunque di controllare 'pszChar! = '\ 0'' in modo esplicito. Non si sta confrontando con 'NULL' (in genere per i puntatori), ma contro il carattere null, che termina le stringhe C. (In alternativa, entrambi sono uguali a zero, quindi 'pszChar && * pszChar' è anche una buona condizione, se ci si trova in quel genere di cose). –

0

sizeof(source) rendimenti sizeof un puntatore come fonte è dichiarato come char *. Modo corretto per usarlo è strlen(source).

successivo:

printf("%s",source[i]); 

aspetta stringa. i.e% s si aspetta una stringa ma tu stai iterando in un ciclo per stampare ogni carattere. Quindi utilizzare% c.

Tuttavia il tuo modo di accedere (iterando) a una stringa usando l'indice i è corretto e quindi non ci sono altri problemi in esso.

Problemi correlati