Разделить строку на две в зависимости от местоположения символа

Мне нужно разбить строку на строку в зависимости от местоположения символа. Так что:

str1 = "привет? мир" это str1 = "привет" и str2 = "мир"

Это то, что у меня есть до сих пор:

    char    str1[100] = "hello?world";
    char    str2[100];
    char    *p;

    p = strpbrk(str1, "?");
    strcpy(&str2, p);

    strcspn(str1, '?');

Я получаю ошибки при попытке скопировать символы после 'p' в str2. Должен быть лучший и функциональный способ. Кто-нибудь может мне помочь? Большое спасибо...


person Kreuzade    schedule 27.09.2012    source источник
comment
strcpy(&str2, p); должно быть strcpy(str2, p); (ну, p+1, так как p указывает на '?', а вам нужны вещи после, если я правильно понял). Но это не должно вызывать ошибки. Какие ошибки вы получаете?   -  person Daniel Fischer    schedule 27.09.2012
comment
@DanielFischer Удаление «&» исправило ошибку для меня. И да, мне нужен p + 1. Думаю, я был намного ближе, чем думал, потому что теперь он у меня работает. Спасибо!   -  person Kreuzade    schedule 27.09.2012
comment
Это странно (если только ошибка не была ошибкой компиляции из-за -Werror). Хотя &str2 является char (*)[100], адрес str2 совпадает с адресом str2[0], который вы получите, если передадите str2. Таким образом, за исключением некоторых эзотерических реализаций, где указатели на разные типы имеют разные представления, strcpy(&str2, p) должно вызывать предупреждение, но работать.   -  person Daniel Fischer    schedule 27.09.2012


Ответы (4)


Этот

strcspn(str1, '?');

является ошибкой, strcspn вторым параметром является const char*, передача символьной константы почти наверняка вызовет неопределенное поведение и ошибку сегментации (маловероятно, что ваша программа будет иметь адрес 63 (значение ASCII '?') в своем адресном пространстве , а если и есть, то маловероятно, что он указывает на массив символов, заканчивающийся 0).

p = strpbrk(str1, "?");
strcpy(str2, p+1);

должно работать. Если вы хотите закончить str1 на '?', *p = 0; перезапишет '?' с 0. Но, конечно, обычно вы должны убедиться, что strpbrk не возвращает NULL перед использованием p.

person Daniel Fischer    schedule 27.09.2012

&str2 — это указатель на массив [100]. Вам действительно следует использовать адрес str2. Кроме того, вторым параметром strcspn должно быть "?" (строка с завершающим нулем) вместо '?' (один символ).
Кроме того, следующий код работает нормально:

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

char s[] = "hello?world"; /* source string */

char s1[100] = ""; /* first part */
char s2[100] = ""; /* second part */

char *tmp = strchr(s, '?');

if (tmp != NULL) {
    *tmp = '\0';
    strcpy(s1, s);
    strcpy(s2, tmp+1);
}

puts(s1);
puts(s2);
person md5    schedule 27.09.2012

Я не знаю так много строковых функций stdlib, но вы можете сделать это (ваши строки будут «безопасными», я имею в виду, что вам не придется выделять слишком много байтов, а только необходимые байты, поэтому код будет немного длинным) :

int main()
{
  char *tmp;
  char *s1;
  char *s2;
  char delim;
  int i;
  int j;

  tmp = strdup("hello?world");
  delim = '?';
  i = 0;
  while (s1[i] != delim)
   i++;
  j = 0;
  s1 = malloc(i + 1);
  while (j < i)
   {
    s1[j] = tmp[j];
    j++;
   }
  s1[j + 1] = '\0';
  j = 0;
  i++;
  while (tmp[i])
   {
    i++;
    j++;
   }
  i = strlen(tmp) - j;
  s2 = malloc(j + 1);
  j = 0;
  while (tmp[i])
   {
    s2[j] = tmp[i];
    j++;
    i++;
   }
  s2[j + 1] = '\0';
}

Я надеюсь, что это поможет вам.

person Simon MILHAU    schedule 27.09.2012
comment
Почему бы вам не использовать циклы for? - person md5; 27.09.2012
comment
Я изучал код в своей школе, и нам не разрешалось его использовать (как break, switch, printf и все производные (?)) и нас учили использовать системные вызовы и помещать char за char. Так что мой код C может показаться странным программистам-самоучкам. Мои извинения, если это может быть длинным или странным для эксперта C - person Simon MILHAU; 27.09.2012

Используйте strtok(). Перейдите по ссылке, чтобы увидеть пример.

Сделайте что-то вроде этого:

   char    src[] = "hello?world";
   char    str1[100];
   char    str2[100];
   char    *p;

   p = strtok(src, "?");
   strcpy(str1, p);

   p = strtok(NULL, "?");
   strcpy(str2, p);
person Neil    schedule 27.09.2012
comment
src должен быть массивом, а не указателем, потому что strtok изменяет свой аргумент. Это может вызвать ошибку сегментации. - person md5; 27.09.2012