манипулирование строками без выделения памяти в c - PullRequest
1 голос
/ 06 мая 2010

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

const char *str = "9|0\" 940 Hello";

В настоящее время я получаю 940, то есть подстроку, которую я хочу,

char *a = strstr(str,"9|0\" ");
char *b = substr(a+5, 0, 3); // gives me the 940

Где substr - моя процедура подстроки. Дело в том, что я не хочу выделять для этого память, вызывая процедуру подстроки.

Есть ли намного более простой способ? Возможно, путем некоторой манипуляции со строками и без выделения памяти.

Буду благодарен за любые отзывы.

Ответы [ 5 ]

2 голосов
/ 06 мая 2010

Нет, это не может быть сделано. По крайней мере, не без изменения исходной строки и не отходя от обычного понятия C о том, что такое строка.

В C строка - это последовательность символов, оканчивающаяся NUL (символ \0). Чтобы получить из "9|0\" 940 Hello" подстроку "940", в памяти должна быть последовательность символов 9, 4, 0, \0. Поскольку эта последовательность символов не существует нигде в вашей исходной строке, вам придется изменить исходную строку.

Другой вариант будет просто использовать указатель на исходную строку в том месте, где начинается желаемая подстрока, а затем также помнить, как долго ваша подстрока должна быть вместо завершающего символа \0. Однако все стандартные функции библиотеки C, работающие со строками (и почти все сторонние библиотеки C, работающие со строками) ожидают, что строки заканчиваются NUL, и поэтому не будут принимать этот формат указателя и числа.

1 голос
/ 06 мая 2010

Попробуйте это:

char *mysubstr(char *dst, const char *src, const char *substr, size_t maxdst) {
    ... do substr logic, but stick result in dst respecting maxdst ...
}

По сути, добавьте и позвольте вызывающей стороне распределить пространство в стеке с помощью:

char s[100];

Или что-то.

0 голосов
/ 06 мая 2010

Если вам не нужна завершенная строка \ 0, вы можете создать функцию поиска подстроки, которая просто сообщает вам, где в полной строке (стоге сена) находится ваша частичная строка (игла). Это будет считаться горячей копией или псевдонимом, поскольку данные могут быть изменены путем изменения полной строки (стог сена).

Я долго писал о том, как распределить память, используя alloca и реализовать макрос (потому что он не будет работать как функция), который будет делать то, что вы хотите, но случайно натолкнулся на strndupa что похоже на strndup, за исключением того, что выделяет память в стеке, а не из кучи. Это расширение GNU, поэтому оно может быть недоступно для вас.

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

0 голосов
/ 06 мая 2010

Как и предполагал xyld, вы можете позволить вызывающей стороне выделить память и передать вашей функции substr буфер для заполнения; хотя, строго говоря, это все еще включает «выделение памяти».

Без выделения какой-либо памяти, единственный способ сделать это - изменить исходную строку, изменив символ после подстроки на '\0', но, конечно, ваша функция не смогла бы возьмите const char * больше, и вы изменяете исходную строку, что может быть нежелательно.

0 голосов
/ 06 мая 2010

Строка C - это просто массив символов в памяти. Если вы хотите получить доступ к подстроке без выделения копии символов, вы можете просто получить к ней прямой доступ:

char *b = a[5];

Проблема с этим подходом состоит в том, что b не будет завершаться нулем до соответствующей длины. По сути, это будет указатель на строку: «940 привет».

Если это не имеет значения для кода, который использует b, тогда вы готовы. Имейте в виду, однако, что это, вероятно, удивит других программистов позже в жизни продукта (включая вас)!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...