2009-11-13 5 views
24

Ich habe eine C-Zeichenfolge, die wie "Nmy stringP" aussieht, wobei N und P ein beliebiges Zeichen sein können. Wie kann ich es in "my string" in C bearbeiten?Strip erste und letzte Zeichen von C-String

+2

Hausaufgaben? Fügen Sie das "Hausaufgaben" -Tag hinzu, wenn dies der Fall ist. – pmg

+0

Nein, nicht Hausaufgaben - nur versuchen, C zum Spaß zu lernen. – igul222

+1

In reinem C gibt es keine "Zeichenfolge". Haben Sie einen Zeiger auf einen Puffer ('char *') oder ein Zeichen-Array ('char []')? –

Antwort

46

zu „entfernen“ den ersten Zeichenpunkt zum zweiten Charakter:

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

das letzte Zeichen ersetzen Sie es mit einem ‚\ 0‘

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

Dies funktioniert möglicherweise nicht, da der Compiler/Linker durch die Initialisierung von "Nmy stringP" als Literal in den schreibgeschützten Speicher versetzt werden kann, wodurch die Bearbeitung fehlschlägt. – Suppressingfire

+8

@Suppressingfire: "Nmy stringP" ist in der Tat eine literale Zeichenfolge, aber es wird (char von char) in das Array "mystr" kopiert. Das Array 'mystr' ist änderbar. – pmg

+0

@pmg: Wo kopierst du? 'char * p = mystr' zeigt' p' auf 'mystr', es kopiert nicht' mystr'. – quark

1

Der effizienteste Weg, zu entfernen:

//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); 

Der sicherste Weg:

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); 

Der zweite Weg ist weniger effizient, aber es ist sicherer, weil Sie String-Literale als Eingabe übergeben können. Sie können strdup auch für den zweiten Weg verwenden, wenn Sie es nicht selbst implementieren möchten.

+0

Das Problem, das ich bei deiner zweiten Implementierung sehe, ist, dass du sicherstellen musst, dass deine Ausgabe groß genug ist um die Kopie zu verarbeiten, bevor Sie getAllBufFirstAndLast() aufrufen. In diesem Fall würde ich empfehlen, eine outputLength-Variable zum Aufruf hinzuzufügen und die aufgerufene Funktion die Ausgabe mit strn * -Funktionen manipulieren zu lassen. – shank

+0

ja, das ist eine Voraussetzung, yup Sie können einen Längenparameter hinzufügen. –

9

Eine weitere Möglichkeit, wieder unter der Annahme, dass „Bearbeiten“ bedeutet, dass Sie anstelle ändern möchten:

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; 
} 

Diese die Zeichenfolge anstelle ändert, ohne eine neue Adresse zu erzeugen als PMG-Lösung der Fall ist. Nicht dass mit pmgs Antwort etwas nicht stimmt, aber in manchen Fällen ist es nicht das, was Sie wollen.

2

Im Anschluss an @ PMG Antwort, beachten Sie, dass beide Vorgänge in einer Anweisung tun:

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

Dies dürfte wie erwartet funktionieren wird, aber das Verhalten ist in C-Standard nicht definiert.

+0

Es ist am besten, sich nicht auf undefiniertes Verhalten zu verlassen. – T0xicCode

+1

@ xav0989 Einverstanden, wollte ich hinzufügen, dass mehr als Kommentar (um den Grund dafür nicht zu markieren), nicht als alternative Antwort. Ich bin ein bisschen neu dabei. –