Подтвердить что ты не робот

Хорошая библиотека строк C

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

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

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

Любая помощь очень ценится. Заранее спасибо!

РЕДАКТИРОВАТЬ: меня спросили о лицензии, которую я предпочитаю. Подойдет любая лицензия с открытым исходным кодом, но желательно GPL (v2 или v3).

EDIt2: Я нашел библиотеку betterString (bstring), и она выглядит довольно хорошо. Хорошая документация, небольшой, но универсальный набор функций, и его легко смешивать со строками c. У кого-нибудь есть хорошие или плохие истории об этом? Единственный недостаток, о котором я читал, это то, что в нем отсутствует Юникод (опять же, читайте об этом, пока еще не видел его лицом к лицу), но все остальное кажется довольно хорошим.

EDIT3: Кроме того, предпочтительнее, чем его чистый C.

4b9b3361

Ответ 1

Это старый вопрос, надеюсь, вы уже нашли полезный. Если вы этого не сделали, проверьте библиотеку Simple Dynamic String на github. Я копирую и вставляю описание автора здесь:

SDS - это строковая библиотека для C, предназначенная для расширения ограниченных функций обработки строк libc путем добавления выделенных в куче строк, которые:

  • Проще в использовании.
  • Бинарный сейф.
  • В вычислительном отношении более эффективный.
  • Но пока... Совместимо с обычными строковыми функциями Си.

Это достигается с помощью альтернативного дизайна, в котором вместо использования структуры C для представления строки мы используем двоичный префикс, который сохраняется до фактического указателя на строку, возвращаемую SDS пользователю.

+--------+-------------------------------+-----------+
| Header | Binary safe C alike string... | Null term |
+--------+-------------------------------+-----------+
         |
         '-> Pointer returned to the user.

Поскольку метаданные хранятся до фактического возвращаемого указателя в качестве префикса, и из-за того, что каждая строка SDS неявно добавляет нулевой термин в конце строки, независимо от фактического содержимого строки, строки SDS хорошо работают вместе со строками C и Пользователь может использовать их взаимозаменяемо с реальными функциями, которые получают доступ к строке только для чтения.

Ответ 2

Я бы предложил не использовать какую-либо библиотеку, кроме malloc, free, strlen, memcpy и snprintf. Эти функции предоставляют вам все инструменты для эффективной, безопасной и эффективной обработки строк в C. Просто держитесь подальше от strcpy, strcat, strncpy и strncat, все из которых, как правило, приводят к неэффективности и уязвимые ошибки.

Поскольку вы упомянули поиск, независимо от выбора библиотеки, которую вы делаете, strchr и strstr почти наверняка будут тем, что вы хотите использовать. strspn и strcspn также могут быть полезны.

Ответ 3

Если вы действительно хотите получить это с самого начала, вы должны посмотреть ICU, то есть поддержку Unicode, если вы не уверены ваши строки никогда не будут содержать ничего, кроме простого ASCII-7... Поиск, регулярные выражения, токенизация все там.

Конечно, переход на С++ упростит ситуацию, но даже тогда моя рекомендация ICU будет стоять.

Ответ 4

Пожалуйста, проверьте milkstrings.
Пример кода:

int main(int argc, char * argv[]) {
  tXt s = "123,456,789" ;
  s = txtReplace(s,"123","321") ; // replace 123 by 321
  int num = atoi(txtEat(&s,',')) ; // pick the first number
  printf("num = %d s = %s \n",num,s) ;
  s = txtPrintf("%s,%d",s,num) ; // printf in new string
  printf("num = %d s = %s \n",num,s) ;
  s = txtConcat(s,"<-->",txtFlip(s),NULL) ; // concatenate some strings
  num = txtPos(s,"987") ; // find position of substring
  printf("num = %d s = %s \n",num,s) ;
  if (txtAnyError()) { //check for errors
    printf("%s\n",txtLastError()) ;
    return 1 ; }
  return 0 ;
  }

Ответ 5

Я также нашел необходимость в внешней библиотеке строк C, поскольку я обнаружил, что функции <string.h> очень неэффективны, например:

  • strcat() может быть очень дорогим по производительности, поскольку он должен найти '\ 0' char каждый раз, когда вы объединяете строку
  • strlen() является дорогостоящим, так как снова он должен найти '\ 0' char вместо того, чтобы просто читать поддерживаемую переменную length
  • Массив char, конечно, не является динамическим и может привести к очень опасным ошибкам (авария при сегментировании может быть хорошим сценарием при переполнении вашего буфера)

Решение должно быть библиотекой, которая не содержит только функции, но также содержит структуру, которая обертывает строку и позволяет хранить важные поля, такие как length и buffer-size

Я искал такие библиотеки через Интернет и нашел следующее:

Enjoy

Ответ 6

Недавно я столкнулся с этой проблемой - необходимость добавления строки с миллионами символов. Я закончил свою работу.

Это просто массив массивов C, инкапсулированный в класс, который отслеживает размер массива и количество выделенных байтов.

Производительность по сравнению с SDS и std::string в 10 раз выше с показателем ниже

в

https://github.com/pedro-vicente/table-string

Бенчмарки

Для Visual Studio 2015, отладка сборки x86:

| API                   | Seconds           
| ----------------------|----| 
| SDS                   | 19 |  
| std::string           | 11 |  
| std::string (reserve) | 9  |  
| table_str_t           | 1  |  

clock_gettime_t timer;
const size_t nbr = 1000 * 1000 * 10;
const char* s = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
size_t len = strlen(s);
timer.start();
table_str_t table(nbr *len);
for (size_t idx = 0; idx < nbr; ++idx)
{
  table.add(s, len);
}
timer.now("end table");
timer.stop();

ИЗМЕНИТЬ Максимальная производительность достигается путем назначения всей строки в начале (размер параметра конструктора). Если используется доля общего размера, производительность падает. Пример со 100 выделениями:

std::string benchmark append string of size 33, 10000000 times
end str:        11.0 seconds    11.0 total
std::string reserve benchmark append string of size 33, 10000000 times
end str reserve:        10.0 seconds    10.0 total
table string benchmark with pre-allocation of 330000000 elements
end table:      1.0 seconds     1.0 total
table string benchmark with pre-allocation of ONLY 3300000 elements, allocation is MADE 100 times...patience...
end table:      9.0 seconds     9.0 total