{"id":15049260,"url":"https://github.com/rphii/c-string","last_synced_at":"2026-01-02T13:07:25.497Z","repository":{"id":208523090,"uuid":"721835451","full_name":"rphii/c-string","owner":"rphii","description":"C string implementation, based off of a generic vector implementation","archived":false,"fork":false,"pushed_at":"2024-01-29T02:25:25.000Z","size":51,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-20T20:41:06.604Z","etag":null,"topics":["c","c-string","c99","generic","mutable","string","strings"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rphii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-21T21:45:26.000Z","updated_at":"2024-01-29T01:05:07.000Z","dependencies_parsed_at":"2024-01-29T02:46:45.407Z","dependency_job_id":"e88eece0-703a-4a88-ac63-fd909099522c","html_url":"https://github.com/rphii/c-string","commit_stats":null,"previous_names":["rphii/c-string"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rphii%2Fc-string","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rphii%2Fc-string/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rphii%2Fc-string/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rphii%2Fc-string/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rphii","download_url":"https://codeload.github.com/rphii/c-string/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243505960,"owners_count":20301619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","c-string","c99","generic","mutable","string","strings"],"created_at":"2024-09-24T21:19:19.672Z","updated_at":"2026-01-02T13:07:25.455Z","avatar_url":"https://github.com/rphii.png","language":"C","readme":"# Things may still change\n# Very untested as of now\n- I have no time to write more tests ;\\_;\n\n# c-string\nWIP... Relies on a [generic vector implementation](https://www.github.com/rphii/c-vector).\n\n- The code is C99 (and upwards) compatible. Compiles with gcc, tcc, clang\n- The **goal** is dynamically easy to use, fast, reusable and secure handling of strings.\n- The **idea** is making use of a *generic vector* and expanding it to fit our needs. (*In fact,\n  there is currently only one function implemented within `str.c`, that is `str_fmt` which acts\n  similarly to how `sprintf` would. Everything else comes from `vec.h`)*\n- Clean your strings with `str_free`\n\n## Example\n```c\n#include \"str.h\"\n\nint main(void)\n{\n    Str string = {0};\n\n    printf(\"string is %s empty\\n\", str_empty(\u0026string) ? \"indeed\" : \"not\");\n\n    str_fmt(\u0026string, \"Hello\"); /* str_fmt always appends... I basically only ever use this function :) */\n    str_push_back(\u0026string, ',');\n    str_push_back(\u0026string, ' ');\n    str_fmt(\u0026string, \"World!\");\n\n    printf(\"string is %s empty\\n\", str_empty(\u0026string) ? \"indeed\" : \"not\");\n    printf(\"back of string  : %c\\n\", str_get_back(\u0026string)); /* '!' */\n    printf(\"front of string : %c\\n\", str_get_front(\u0026string)); /* 'H' */\n\n    printf(\"%s\\n\", string.s); /* \"Hello, World!\" */\n    printf(\"string length : %zu\\n\", str_length(\u0026string)); /* 13 */\n\n    str_reverse(\u0026string);\n    printf(\"%s\\n\", string.s); /* \"!dlroW ,olleH\" */\n\n    str_swap(\u0026string, 0, str_length(\u0026string) - 1);\n    printf(\"%s\\n\", string.s); /* \"HdlroW ,olle!\" */\n\n    Str copy = {0};\n    str_copy(\u0026copy, \u0026string);\n    printf(\"%s\\n\", copy.s); /* \"HdlroW ,olle!\" */\n\n    printf(\"reserved %zu bytes [in string]\\n\", str_reserved(\u0026string)); /* 32 bytes */\n    str_clear(\u0026copy);\n    printf(\"cleared string: [%.*s]\\n\", STR_F(\u0026copy)); /* !!! anytime printing anything, this is the correct way of doing so !!! (see 12 lines below; direct access to .s field may or may not be dangerous, especially if there are operations (such as pop) happening at the front of the string !!!) */\n    str_fmt(\u0026copy, \"re-using those %zu byes!\", str_reserved(\u0026copy));\n    printf(\"string fmt after clear: %s\\n\", copy.s);\n    str_free(\u0026copy);\n    printf(\"reserved %zu bytes after free [in copy]\\n\", str_reserved(\u0026copy)); /* 0 bytes */\n    printf(\"reserved %zu bytes after all above [in string]\\n\", str_reserved(\u0026string)); /* 32 bytes */\n\n    char pop = 0;\n    str_pop_front(\u0026string, \u0026pop); /* pop is an optional argument, pass 0 to ignore */\n    printf(\"pop front : %c\\n\", pop); /* 'H' */\n    str_pop_back(\u0026string, \u0026pop);\n    printf(\"pop back  : %c\\n\", pop); /* '!' */\n    printf(\"string after pop : %s [expected to be incorrect, mainly due to directly accessing the struct] \\n\", string.s); /* \"HdlroW ,olle!\" */\n    printf(\"string after pop : %.*s [correct access]\\n\", STR_F(\u0026string)); /* \"dlroW ,olle\" */\n\n    str_shrink(\u0026string);\n    printf(\"string after shrink : %s\\n\", string.s); /* \"dlroW ,olle\" */\n\n    str_push_front(\u0026string, '_');\n    str_insert_at(\u0026string, 3, 'X');\n    str_set_at(\u0026string, 10, 'Y');\n    printf(\"after modification : %s\\n\", string.s); /* \"_dlXroW ,oYle\" */\n    printf(\"string length : %zu\\n\", str_length(\u0026string)); /* 13 */\n\n    str_free(\u0026string); /* clean up */\n    printf(\"after free reserved %zu bytes\\n\", str_reserved(\u0026string)); /* 0 bytes */\n    printf(\"string length : %zu\\n\", str_length(\u0026string)); /* 0 */\n\n    return 0;\n}\n```\n\n## TODO so I won't forget\n- lower\n- upper\n- concat etc -\u003e vec\n- find etc -\u003e vec\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frphii%2Fc-string","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frphii%2Fc-string","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frphii%2Fc-string/lists"}