26 votes

Comment supprimer le premier caractère d'une chaîne de caractères C ?

Quelqu'un peut-il m'aider ? Je dois supprimer le premier caractère d'un char * en C.

Par exemple, char * contents contient un '\n' comme premier caractère du tableau. J'ai besoin de détecter et d'éliminer ce caractère, en modifiant la variable originale après qu'elle ait été "nettoyée".

Quelqu'un peut-il m'aider avec le code ? Je suis complètement novice en C, et je n'arrive pas à le comprendre.

64voto

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

Ou, si le pointeur peut être modifié :

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

24voto

char* contents_chopped = contents + 1;

Cela se traduira par contents_chopped pointant sur la même chaîne, sauf que le premier caractère sera le suivant après \n

De plus, cette méthode est plus rapide.

15voto

mfisch Points 659

Ne vous contentez pas d'incrémenter le pointeur si vous avez alloué de la mémoire, sinon votre programme se plantera. free a besoin du pointeur d'origine. Vous pouvez copier le pointeur, créer un nouveau morceau de mémoire et l'envoyer par memcpy, y accéder en tant que ptr+1 ou de toute autre manière, mais les personnes qui disent qu'il suffit d'incrémenter le pointeur vous donnent des conseils dangereux. Vous pouvez exécuter cet exemple de programme et voir ce qui se passe lorsque vous "incrémentez simplement le pointeur".

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

Indice : voici le résultat :

[mfisch@toaster ~]$ ./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

4voto

Karl Knechtel Points 24349

On dirait que vous avez l'impression qu'un char* "contient" des caractères. Ce n'est pas le cas. Il ne fait que points en a parte. Le reste de la chaîne est implicitement constitué de l'octet suivant en mémoire jusqu'à l'octet nul suivant. (Vous devez également savoir que, bien que le type de données 'char' soit un octet, par définition, ce n'est pas vraiment un caractère - veuillez tenir compte d'Unicode - et un octet n'est pas non plus nécessairement un octet).

Le char* n'est pas non plus un tableau, bien qu'il puisse exister un tableau de caractères tel que le pointeur pointe vers le début de ce tableau.

2voto

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

int main ()
 {
char src[50] = "123456789123434567678";

char dest[16]={0};
 memcpy(dest, src+1,sizeof(src));
 printf("%s\n",dest);
 return(0);
}

src+1 -> indicate how many char you want to remove

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X