LINUX.ORG.RU

Работа с массивом на СИ

 ,


0

2

Здравствуйте.

Суть вот в чём: мне нужно проверить наличие подстроки (она всегда в самом начале строки) в строке, и всё что идёт после этой подстроки записать в другой массив.

Допустим делаю так:

char *restr;
char str[32] = {0,};
char res_mas[16] = {0,};
...

if((restr = strstr(str, "xa-xa")) != NULL) 
 {
   strcpy(res_mas, restr + 5);
...

То есть я сдвигаю указатель на длину подстроки и оставшееся копирую в конечный массив.

Вопрос заключается в том, могу ли я сделать так?

char str[32] = {0,};
char res_mas[16] = {0,};
...

if(strstr(str, "xa-xa") != NULL) 
 {
   strcpy(res_mas, str + 5);
...

В обоих случаях всё работает, но правильно ли так делать?

(только не пишите пожалуйста, что лучше использовать strncpy или memcpy, речь не об этом, strcpy нарисована в качестве примера)

...

И ещё «подвопрос»: если я использую несколько конструкций «if()» подряд...

char *restr;
char str[32] = {0,};
char res_mas[16] = {0,};
char res_mas2[16] = {0,};
char res_mas3[16] = {0,};
...

if((restr = strstr(str, "xa-xa")) != NULL) 
 {
   strcpy(res_mas, restr + 5);
 }

if((restr = strstr(str, "xo-xo")) != NULL) 
 {
   strcpy(res_mas2, restr + 5);
 }

if((restr = strstr(str, "xy-xy")) != NULL) 
 {
   strcpy(res_mas3, restr + 5);
 }

...то нужно ли после каждого блока if() «обнулять» указатель *restr? И если да, то как это делать правильно?

Заранее спасибо.


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


int main(int argc, char ** argv)
{
    if (argc != 3)
        return 1;

    const char * str1 = argv[1];
    const char * str2 = argv[2];

    size_t size1 = strlen(str1);
    size_t size2 = strlen(str2);

    char * result = NULL;

    if (size1 >= size2 && memcmp(str1, str2, size2) == 0)
    {
        size_t result_size = size1 - size2;
        result = malloc(result_size);
        memcpy(result, str1 + size2, result_size);
    }

    printf("Original string: %s\n", str1);
    printf("Prefix: %s\n", str2);

    if (result)
    {
        printf("The string with prefix removed: %s\n", result);
        free(result);
    }
    else
    {
        printf("The string has no prefix!\n");
    }

    return 0;
}
vadim@aquila:/tmp$ gcc -Wall 111.c
vadim@aquila:/tmp$ ./a.out qwerty qwe
Original string: qwerty
Prefix: qwe
The string with prefix removed: rty
vadim@aquila:/tmp$ ./a.out qwerty 1qwe
Original string: qwerty
Prefix: 1qwe
The string has no prefix!
vadim@aquila:/tmp$ ./a.out qw qwe
Original string: qw
Prefix: qwe
The string has no prefix!
vadim@aquila:/tmp$ 
Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)

Если ты абсолютно уверен в том, что подстрока начинается с с нулевого смещения, то надобность в дополнительной сущности такой как restr отпадает. Таким образом, второй фрагмент кода возможно будет немного эффективнее в связи с отсутствием лишнего присваивания. Что касается второго вопроса, ты не обязан обнулять указатель, функция и так его обновит.

anonymous
()
restr + 5

Магические константы — это так мило. Happy debugging после изменения размера строки.

Deleted
()
Ответ на: комментарий от Deleted

Happy debugging после изменения размера строки.

И особенного счастья для строки «xa-xa», ведь автор наверняка в юникоде.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Не, это латиница. Я скопипастил в hex-редактор.

Но по виду совершенно невозможно понять, сколько там байт, да.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Sorcerer

И особенного счастья для строки «xa-xa»

Там написано - иксэй-иксэй. А вобще, это для примера, с юмористическим уклоном. Люди улыбнутся, людям будет приятно. Социальная инженерия))).

stD
() автор топика
Ответ на: комментарий от Deleted

Магические константы — это так мило

Полностью согласен, однако писано для себя и меняться не будет.

stD
() автор топика
Ответ на: комментарий от stD

меняться не будет

Фраза, с которой начиналось столько невероятных IT-приключений...

Deleted
()
Ответ на: комментарий от anonymous

Если ты абсолютно уверен в том, что подстрока начинается с с нулевого смещения

Да, уверен абсолютно. Благодарю.

ты не обязан обнулять указатель, функция и так его обновит

Вот здесь не понял, объясните чуть подробнее, при каких обстоятельствах нужно обнулять указатель?

stD
() автор топика
Ответ на: комментарий от Deleted

Ни при каких. (Какой вопрос, такой ответ.)

Извиняюсь. Просто понимание указателя пока не полностью усвоилось в моей голове, отсюда такие дурацкие вопросы.

stD
() автор топика
Ответ на: комментарий от Deleted

devzero скажите, в моём случае будет правильней использовать функцию memcmp? Она будет быстрее чем strstr?

stD
() автор топика
Ответ на: комментарий от stD

Как вообще memcmp с strstr сравнивать? Они вообще разные вещи делают. Вы определитесь с тем, где данные искать нужно.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

В моём примере подстрока ищется с помощью strstr, а в примере приведённом devzero, с помощью memcmp. Поэтому и спросил.

stD
() автор топика
Ответ на: комментарий от stD

strstr ищет подстроку где угодно внутри строки, а не только в начале.

Sorcerer ★★★★★
()
Ответ на: комментарий от anonymous

Разве недостаточно вручную запихивать «\0» в конец, а передавать в функцию на одно значение меньше чем длина буфера? А так да, можно использовать и strlcpy, добавив файлы с этими функциями, если они отсутствуют в реализации.

grem ★★★★★
()
Ответ на: комментарий от stD

добавь к if((restr = strstr(str, "xa-xa")) != NULL) сравнение указателей (restr == str) раз уж тебе нужно, чтобы дальше выполнялось только если искомая строка в начале, или что-то такое.

grem ★★★★★
()
Ответ на: комментарий от anonymous

Никогда, никогда, никогда не используйте strncpy!!!

Вообще смотреть на str* в сишном коде сплошная боль. Код неэффективный и почти всегда опасный. Возникает один только вопрос - зачем? Если уж выбрал С, то используй его эффективно, храни размер и используй mem*.

anonymous
()
Ответ на: комментарий от Kroz

strncpy(...) !!!

В посте я писал:

(только не пишите пожалуйста, что лучше использовать strncpy или memcpy, речь не об этом, strcpy нарисована в качестве примера)

stD
() автор топика
Ответ на: комментарий от anonymous

Вообще смотреть на str* в сишном коде сплошная боль.

Но ведь зачем-то их туда впилили...

stD
() автор топика
Ответ на: комментарий от grem

только если искомая строка в начале,

Я знаю что она в начале, я проверяю только её наличие. Да и не об этом был вопрос.

stD
() автор топика
Ответ на: комментарий от stD

Я знаю что она в начале, я проверяю только её наличие.

Так тебе надо «уxa-xa-ху» захватывать или не надо? Гражданин, определитесь.

Deleted
()
Ответ на: комментарий от stD

Да и не об этом был вопрос.

Вопрос о том, что у тебя в целом код через задницу.

Я тебе показал пример кода — бери и используй. Или нужно не просто решить твою домашку за тебя, а еще и заставить её ходить на твоих же кривых костылях? С этим в Jobs.

Deleted
()
Ответ на: комментарий от Deleted

Так тебе надо «уxa-xa-ху» захватывать или не надо?

Захватывать «ха-ха» мне НЕ надо, мне надо узнать есть ли «ха-ха» в строке и если есть, то захватить то, что идёт после неё.

Пример строки:

«ха-хадальше то, что мне нужно»

stD
() автор топика
Ответ на: комментарий от Deleted

Или нужно не просто решить твою домашку за тебя

Не кипятись. Никаких домашек мне давно уже решать не надо.

Ответ на свой вопрос я получил во втором комменте, сразу после твоего кода, за который, кстати, благодарю.

stD
() автор топика
Ответ на: комментарий от grem

В том то и дело, что у тебя кусок кода выполняется, даже если искомая часть окажется не в начале.

Я знаю.

stD
() автор топика
Ответ на: комментарий от stD

лови алаверды

пробел(space) не забой(backspace)

как и 755 отправленных на родинку

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.