2009-11-13 19 views
24

Tengo una cadena C que se parece a "Nmy stringP", donde N y P pueden ser cualquier carácter. ¿Cómo puedo editarlo en "my string" en C?Strip primer y último carácter de la serie C

+2

¿Tarea? Agregue la etiqueta "tarea" si es así. – pmg

+0

No, no es tarea, solo estoy tratando de aprender C por diversión. – igul222

+1

En C puro, no existe una "cadena". ¿Tiene un puntero a un búfer ('char *') o una matriz de caracteres ('char []')? –

Respuesta

46

de "eliminar" el primero punto de carácter para el segundo carácter:

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

Para eliminar el último carácter reemplazarlo con un '\ 0'

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

Esto puede no funcionar porque al inicializar "Nmy stringP" como un literal, el compilador/enlazador puede colocarlo en la memoria de solo lectura, lo que hace que la edición falle. – Suppressingfire

+8

@Suppressingfire: "Nmy stringP" es de hecho una cadena literal, pero se copia (char por char) a la matriz 'mystr'. La matriz 'mystr' es modificable. – pmg

+0

@pmg: ¿Dónde estás copiando? 'char * p = mystr' apunta' p' a 'mystr', no copia' mystr'. – quark

1

La forma más eficiente:

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

La forma más segura:

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

La segunda forma es menos eficiente pero es más segura porque puede pasar literales de cadena a la entrada. También podría usar strdup de la segunda manera si no quisiera implementarlo usted mismo.

+0

El problema que veo con su segunda implementación es que necesita asegurarse de que su salida sea lo suficientemente grande para manejar la copia antes de llamar a getAllBufFirstAndLast(). En este caso, recomendaría agregar una variable outputLength a la llamada y dejar que la función llamada manipule la salida con las funciones strn *. – shank

+0

sí, eso es una condición previa, pero puedes agregar un parámetro de longitud. –

9

Otra opción, asumiendo una vez más que "editar" significa que desea modificar en su lugar:

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

Esto modifica la secuencia en el lugar, sin generar una nueva dirección como la solución de PMG hace. No es que haya algo malo con la respuesta de pmg, pero en algunos casos no es lo que quieres.

2

relación con la respuesta de @ PMG, tenga en cuenta que usted puede hacer ambas operaciones en una declaración:

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

Esto probablemente va a funcionar como se esperaba, pero el comportamiento no está definido en la norma C.

+0

Lo mejor es no confiar en un comportamiento indefinido. – T0xicCode

+1

@ xav0989 De acuerdo, tenía la intención de agregar eso más como un comentario (para resaltar la razón por la que no se hace), no como una respuesta alternativa. Soy un poco nuevo en esto. –

Cuestiones relacionadas