2009-11-13 14 views
24

Ho una stringa C che assomiglia a "Nmy stringP", dove N e P possono essere qualsiasi carattere. Come posso modificarlo in "my string" in C?Striscia primo e ultimo carattere dalla stringa C

+2

Compiti? Aggiungi il tag "compiti" se lo è. – pmg

+0

No, non fare i compiti, solo cercando di imparare C per divertimento. – igul222

+1

Nella pura C non esiste una "stringa". Avete un puntatore a un buffer ('char *') o un array di caratteri ('char []')? –

risposta

46

"togliere" il punto di carattere 1 ° al secondo personaggio:

char mystr[] = "Nmy stringP"; 
char *p = mystr; 
p++; /* 'N' is not in `p` */ 

Per rimuovere l'ultimo carattere sostituirlo con un '\ 0'

p[strlen(p)-1] = 0; /* 'P' is not in `p` (and it isn't in `mystr` either) */ 
+3

Questo potrebbe non funzionare perché inizializzando "Nmy stringP" come letterale, il compilatore/linker può inserirlo nella memoria di sola lettura, causando il fallimento della modifica. – Suppressingfire

+8

@Suppressingfire: "Nmy stringP" è in effetti una stringa letterale, ma viene copiata (char by char) nell'array 'mystr'. L'array 'mystr' è modificabile. – pmg

+0

@ pmg: dove stai copiando? 'char * p = mystr' punta' p' a 'mystr', non copia' mystr'. – quark

1

Il modo più efficace:

//Note destroys the original string by removing it's last char 
// Do not pass in a string literal. 
char * getAllButFirstAndLast(char *input) 
{ 
    int len = strlen(input); 
    if(len > 0) 
    input++;//Go past the first char 
    if(len > 1) 
    input[len - 2] = '\0';//Replace the last char with a null termination 
    return input; 
} 


//... 
//Call it like so 
char str[512]; 
strcpy(str, "hello world"); 
char *pMod = getAllButFirstAndLast(str); 

Il modo più sicuro:

void getAllButFirstAndLast(const char *input, char *output) 
{ 
    int len = strlen(input); 
    if(len > 0) 
    strcpy(output, ++input); 
    if(len > 1) 
    output[len - 2] = '\0'; 
} 


//... 
//Call it like so 
char mod[512]; 
getAllButFirstAndLast("hello world", mod); 

Il secondo modo è meno efficiente ma è più sicuro perché è possibile passare in letterali stringa in input. Puoi anche usare strdup per il secondo modo se non vuoi implementarlo tu stesso.

+0

Il problema che vedo con la tua seconda implementazione è che devi assicurarti che il tuo output sia abbastanza grande per gestire la copia prima di chiamare getAllBufFirstAndLast(). In questo caso, consiglierei di aggiungere una variabile outputLength alla chiamata e lasciare che la funzione chiamata manipoli l'output con le funzioni strn *. – shank

+0

sì, questa è una precondizione, sì, è possibile aggiungere un parametro di lunghezza. –

9

Un'altra opzione, ancora una volta partendo dal presupposto che "modifica" significa che si desidera modificare in atto:

void topntail(char *str) { 
    size_t len = strlen(str); 
    assert(len >= 2); // or whatever you want to do with short strings 
    memmove(str, str+1, len-2); 
    str[len-2] = 0; 
} 

Questa modifica la stringa in posizione, senza generare un nuovo indirizzo di soluzione pmg fa. Non che ci sia qualcosa di sbagliato nella risposta di pmg, ma in alcuni casi non è quello che vuoi.

2

A seguito di @ PMG risposta, si noti che si possono fare entrambe le operazioni in una dichiarazione:

char mystr[] = "Nmy stringP"; 
char *p = mystr; 
p++[strlen(p)-1] = 0; 

Questo probabilmente funzionerà come previsto, ma il comportamento non è definito nello standard C.

+0

È meglio non fare affidamento su comportamenti indefiniti. – T0xicCode

+1

@ xav0989 D'accordo, intendevo aggiungere altro come commento (per evidenziare la ragione per non farlo), non come risposta alternativa. Sono un po 'nuovo in questo. –

Problemi correlati