Как удалить первый символ из C-строки? - PullRequest
20 голосов
/ 28 ноября 2010

Может кто-нибудь, пожалуйста, помогите мне?Мне нужно удалить первый символ из char * в C.

Например, char * contents содержит символ '\n' в качестве первого символа в массиве.Мне нужно обнаружить и устранить этот символ, изменив исходную переменную после ее «очистки».

Может кто-нибудь помочь мне с кодом?Я совершенно новичок в Си, и, похоже, просто не могу понять это.

Ответы [ 6 ]

52 голосов
/ 28 ноября 2010
if (contents[0] == '\n') 
    memmove(contents, contents+1, strlen(contents));

Или, если указатель можно изменить:

if (contents[0] == '\n') contents++;
21 голосов
/ 28 ноября 2010

char* contents_chopped = contents + 1;

В результате contents_chopped будет указывать на ту же строку, за исключением того, что первый символ будет следующим после \ n

Кроме того, этот метод быстрее.

13 голосов
/ 25 мая 2011

Не нужно просто увеличивать указатель, если у вас есть память malloc, или ваша программа вылетит. бесплатно нужен оригинальный указатель.Вы можете скопировать указатель, создать новый фрагмент памяти и запоминать его, обращаться к нему как ptr + 1 или любым другим способом, но люди, которые говорят, просто увеличивают указатель, дают вам опасный совет.Вы можете запустить этот пример программы и посмотреть, что произойдет, когда вы «просто увеличите указатель».

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

Подсказка: вот результат:

[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
3 голосов
/ 30 ноября 2010

Звучит так, как будто у вас сложилось впечатление, что символ * "содержит" символы. Это не. Это просто указывает на байт. Предполагается, что остальная часть строки состоит из следующего байта в памяти вплоть до следующего нулевого байта. (Вам также следует помнить, что хотя тип данных 'char' является байтом, по определению он на самом деле не является символом - обратите внимание на Unicode - и при этом байт не обязательно является октетом.)

Символ char * также не является массивом, хотя может существовать массив символов, такой, что указатель указывает на начало этого массива.

1 голос
/ 26 марта 2018
#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
0 голосов
/ 24 декабря 2017

Вот мой код

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;

}

...