2010-11-28 22 views
13

¿Alguien puede ayudarme? Necesito eliminar el primer carácter de char * en C.¿Cómo eliminar el primer carácter de C-string?

Por ejemplo, char * contents contiene un carácter '\n' como primer carácter de la matriz. Necesito detectar y eliminar este carácter, modificando la variable original después de haber sido "desinfectada".

¿Alguien me puede ayudar con el código? Soy completamente nuevo para C, y no puedo entenderlo.

+1

Para un novato C, es muy beneficioso para leer sobre ' puntero aritmética'. Google el término, obtendrá muchos éxitos. Esto ayudará a entender de lo que otros están hablando aquí. Por ejemplo: 'char * contents_chopped = contents + 1;'. – biocyberman

Respuesta

41
if (contents[0] == '\n') 
    memmove(contents, contents+1, strlen(contents)); 

O bien, si el puntero se puede modificar:

if (contents[0] == '\n') contents++; 
+2

+1 me ganó. –

+1

ahh, eso es lo que hacen las funciones 'mem' en strings.h cool. ¡Esa primera sugerencia funciona perfectamente! – Ash

+3

y tenga en cuenta que debe utilizar 'memmove', no' memcpy', porque 'memmove' es necesario para manejar la fuente/destino superpuestos correctamente. –

19

char* contents_chopped = contents + 1;

Esto dará lugar a contents_chopped apuntando a la misma cadena, a excepción de que el primer carácter será el siguiente después de \ n

Además, este método es más rápido.

+0

Debe tener en cuenta que la validez del puntero dependerá de la validez de 'contents', por lo que esto es bueno si solo desea hacer algún proceso rápido en' contents_chopped'. También es necesario verificar si hay cadena vacía. – tia

+0

+1 para dar la respuesta que cualquier código del mundo real debería usar. Copiar/mover una cadena entera solo para hacer uso de su cola es una ridícula pérdida de tiempo, pero lamentablemente hay muchos programas que realmente hacen tales cosas ... –

+0

Me gusta lo simple que es, pero no se puede liberar el contenido_chopped, ya que lo necesita –

3

Parece que tiene la impresión de que un char * "contiene" caracteres. No es asi. Simplemente puntos en a byte. El resto de la cadena implica que consiste en el byte subsiguiente en la memoria hasta el siguiente byte nulo. (También debe tener en cuenta que aunque el tipo de datos 'char' es un byte, por definición, no es realmente un carácter, tenga en cuenta que Unicode no es necesariamente un octeto)

The char * tampoco es una matriz, aunque puede existir una matriz de caracteres tal que el puntero apunta al comienzo de esa matriz.

13

No solo incremente el puntero si ha malloc'd cualquier memoria o si su programa se bloqueará. gratuito necesita el puntero original. Puedes copiar el puntero, crear un nuevo trozo de memoria y memcpy it, acceder a él como ptr + 1 o cualquiera de muchas otras maneras, pero las personas que dicen que simplemente incrementa el puntero te están dando consejos peligrosos. Puede ejecutar este programa de ejemplo y ver qué sucede cuando "simplemente incrementa el puntero".

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
int main(void) 
{ 
    char *str = (char *)malloc(10); 
    strcpy(str, "1234567890"); 
    printf("%s\n", str); 
    str++; 
    printf("%s\n", str); 
    free(str); 
} 

Consejo: Aquí está el resultado:

[[email protected] ~]$ ./foo 
1234567890 
234567890 
*** glibc detected *** ./foo: free(): invalid pointer: 0x08c65009 *** 
======= Backtrace: ========= 
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x724591] 
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x725de8] 
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x728ecd] 
./foo[0x80484e3] 
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x6cfbd6] 
./foo[0x80483f1] 
======= Memory map: ======== 
001c9000-001e4000 r-xp 00000000 08:01 2883609 /lib/ld-2.11.1.so 
001e4000-001e5000 r--p 0001a000 08:01 2883609 /lib/ld-2.11.1.so 
001e5000-001e6000 rw-p 0001b000 08:01 2883609 /lib/ld-2.11.1.so 
006b9000-0080c000 r-xp 00000000 08:01 3015690 /lib/tls/i686/cmov/libc-2.11.1.so 
0080c000-0080d000 ---p 00153000 08:01 3015690 /lib/tls/i686/cmov/libc-2.11.1.so 
0080d000-0080f000 r--p 00153000 08:01 3015690 /lib/tls/i686/cmov/libc-2.11.1.so 
0080f000-00810000 rw-p 00155000 08:01 3015690 /lib/tls/i686/cmov/libc-2.11.1.so 
00810000-00813000 rw-p 00000000 00:00 0 
00e4d000-00e4e000 r-xp 00000000 00:00 0   [vdso] 
00fe0000-00ffd000 r-xp 00000000 08:01 2883667 /lib/libgcc_s.so.1 
00ffd000-00ffe000 r--p 0001c000 08:01 2883667 /lib/libgcc_s.so.1 
00ffe000-00fff000 rw-p 0001d000 08:01 2883667 /lib/libgcc_s.so.1 
08048000-08049000 r-xp 00000000 08:01 9700477 /home/mfisch/foo 
08049000-0804a000 r--p 00000000 08:01 9700477 /home/mfisch/foo 
0804a000-0804b000 rw-p 00001000 08:01 9700477 /home/mfisch/foo 
08c65000-08c86000 rw-p 00000000 00:00 0   [heap] 
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b776f000-b7770000 rw-p 00000000 00:00 0 
b7780000-b7783000 rw-p 00000000 00:00 0 
bfc22000-bfc37000 rw-p 00000000 00:00 0   [stack] 
Aborted 
+2

Buen punto, esto me está sucediendo en este momento ya que estoy usando el método de incremento, también estoy viendo un error similar al que se muestra aquí. El único problema con esta respuesta es que no hay una solución de código. –

-1

Aquí está mi código

char * bastakiniSil(char *contents){ 
char *p = malloc(sizeof(*p) * strlen(contents)); 
int i; 
for(i=0; i<strlen(contents); i++) 
{ 
    p[i]=contents[i+1]; 
} 

return p; 

}

Cuestiones relacionadas