Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

51–60 of 329 posts

Re: C Strings and my slow descent to madness

#51
post #27

I don't use null terminated strings. ptr+len struct everywhere. And when I need to call an API, like fopen, I make a temporary copy of that string + the null termination, do my work and then free it. You can printf non-null terminated strings too. Check printf("%.*s", length, strptr).

> You can printf non-null terminated strings too. Check printf("%. s", length, strptr).* I haven't checked yet, but I'm about 90% confident that's UB. Is printf() guaranteed not to read to the end of the string when you give it a length?

Yes, it is. From the C11 spec:

> Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. If the precision is not specified or is greater than the size of the array, the array shall contain a null character.

Re: C Strings and my slow descent to madness

#52
post #3

It's unfortunate the author put the arrays-are-pointers thing so early in the doc, as that's a very beginner-to-C mixup and really nothing at all to do with strings. Otherwise, yep. It's pretty bad. C is a great language, but its string handling is definitely garbage. You get used to it pretty quick, and it's not hard to write a handful of sane wrappers or a simple string library for your own use, but the standard li…

I don't see any mention or insinuations of arrays-are-pointers anywhere in the article. Am I missing something?

This bit:

    But you might be asking. “Why can’t I just assign the source variable directly to the destination variable?”

    int main() {
      char source[] = "Hello, world!";
      char* destination = source;
    
      strcpy(destination, source); // Copy the source string to the destination string
    
      printf("Source: %s\n", source);
      printf("Destination: %s\n", destination);
    
      return 0;
    }
    You can. It’s just that destination now becomes a char* and exists as a pointer to the source character array. If that isn’t what you want them this will almost certainly cause issues.

Re: C Strings and my slow descent to madness

#53

Okay, I agree that by default , C strings are bad. But it doesn't have to stay that way. Someone else in the comments mentioned antirez's sds library for dynamic strings. This works, but you could also easily roll your own. All you need is an init function, and perhaps an assert or other check at the end of it that the string has a nul terminator. At that point, type checking will let you blindly pass those strings (…

The best way to write C is to treat strings as memory locations with characters and nothing more. Every such memory location has an allocated size, either statically at compile-time (with literals and arrays), or dynamically with malloc and friends. Treat string operations as mere memory operations and don't imagine them to be something else. The str* functions from the standard library are just convenience helpers w…

Maybe you could summarize this by saying that C strings are "strings of bytes", not "strings of characters".

Re: C Strings and my slow descent to madness

#54

If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…

Is your framework open sourced?

Re: C Strings and my slow descent to madness

#55

> If we try to print out some Japanese characters… [] The output isn’t what we expect. Yes it is. And I bet on a modern windows version it is too. The terminal has been (probably intentionally) neglected by ms for a long time, but as far as I know this has mostly been fixed on modern windows versions. EDIT: Author admits it later in the text "will be fixed in Windows 11 and Windows Server 2022" Also it says "strlen("…

> The terminal has been (probably intentionally) neglected by ms for a long time,

I don't think it is an intentional lack of care, just a lack of care. Internally MS devs affected by the appalling state of the console just did what the rest of us did and installed an alternative.

> but as far as I know this has mostly been fixed on modern windows versions.

Ish. The default console for powershell is better, but a lot of improvements you might be thinking are in there are in fact only in Windows Terminal (https://en.wikipedia.org/wiki/Windows_Terminal) which is not currently included by default.

Re: C Strings and my slow descent to madness

#56
It's important to mention that strncpy (and also strncpy_s) are really not a strcpy replacement, it's not intended for the same usages. The name is a total misnomer. Do not use strncpy that way!

In any case, strcpy_s (which is a good replacement for strcpy) is part of the C11 standard. I'm confused how that isn't considered portable.

Re: C Strings and my slow descent to madness

#57
post #33

> Our last function is strcmp. It looks at two strings and determines whether they are equal to each other or not. If they are it returns 0. If they aren’t it returns 1. No it doesn’t. RETURN VALUES The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned charac…

Reminds me of the incorrect cast of memcmp() return value that resulted in this bug: https://bugs.mysql.com/bug.php?id=64884

Re: C Strings and my slow descent to madness

#59

> If we try to print out some Japanese characters… [] The output isn’t what we expect. Yes it is. And I bet on a modern windows version it is too. The terminal has been (probably intentionally) neglected by ms for a long time, but as far as I know this has mostly been fixed on modern windows versions. EDIT: Author admits it later in the text "will be fixed in Windows 11 and Windows Server 2022" Also it says "strlen("…

> Also it says "strlen("有り難う")); [...] and the output is… The length of the string is 12 characters". But according to "man strlen": "RETURN VALUE: The strlen() function returns the number of bytes in the string pointed to by s.". It says nothing about "number of characters".

Yeah - when dealing with Unicode, you have to be very clear about whether you're dealing with bytes, runes or glyphs.

Re: C Strings and my slow descent to madness

#60
This is from a C fan: If you are going to do any string heavy work, please use anything else than C (Python is pretty nice for this sort of stuff for instance).

And if you need to use C anyway, then please use anything else than the string functions from the standard library. The C stdlib is (mostly) a leftover from the K&R era when opinions about what makes a good API were very different from today, and C was a much 'harsher' language.

C is pretty nice for a lot of things, but working with strings definitely isn't one of them.

Post reply on HN