6 ms·
Have you tried doing string manipulation in C? ;)
by floatboth 10y ago
Have you tried doing string manipulation in C? ;)
- boduh 10y ago+1
- erelde 10y agoYou can see two of my current school assignement on Github. I try to avoid manipulating strings as much as possible. ;)
- asveikau 10y agoNot OP, but I actually think string manipulation in C is really elegant. Many people who complain about it have too many allocations in their code and are trying to port the allocation-heavy non-C way of thinking to C. The C way I know focuses mainly on character at a time iteration with emphasis on not copying the source string. I'm reminded of a time a colleague needed something like string.split, and working in c++ he filled a std::vector<std::string> with the result. Using a more C way he'd really only have needed a couple of pointers on the stack.
- imron 10y ago> The C way I know focuses mainly on character at a time iteration Ah, yes, the good 'ole C way that only works reliably in English.
- dbaupp 10y agoIt's a little naïve to think it works on English without the coöperation of the users. (Also, less glibly, things like emoji seem to be becoming more and more popular.)
- imron 10y agoIndeed. In fact as we speak I am fixing a bug related to string handling with emojis.
- asveikau 10y agoFunny. You can parse utf-8 character at a time. Some characters advance the pointer by 4 at an iteration and some less.
- dbaupp 10y agoWhat do you mean by "character"? If you mean code point or "unicode scalar value", sure, but if you mean user-visible character (grapheme), it's much more complicated: even something "simple" like ö could be one or two code points.
- asveikau 10y agoI mean your iterator is char* and you advance it by adding. That's it. I do NOT mean that char itself corresponds to a glyph or codepoint, you are seriously preaching to the choir making that lecture to me.
- fauigerzigerk 10y ago>you advance it by adding And when do you stop? UTF-8 strings can have zero bytes in them so treating them as C strings is potentially error prone depending on the context.
- asveikau 10y agoUnless you have U+0000 there isn't any other sequence of code points that has an 0x00 byte in UTF-8. I don't see this as a huge problem. If you really do need it there are some C language libraries that use "pascal-ish" structs to do strings. UNICODE_STRING in Windows comes to mind. Doing strings in C doesn't force you to use C strings, it's just the most common thing to do.
- fauigerzigerk 10y agoNo it's not a huge problem, but if you're not aware of it, it could easily lead to a security breach: https://news.ycombinator.com/item?id=13974919 https://news.ycombinator.com/item?id=13974919
- cat199 10y agoSo it's somehow C's fault that Unicode uses variable-length encoding, which is automatically going to be harder to process correctly at a byte-by-byte level than a fixed-length method, and also included known-C-incompatible null bytes?
- imron 10y ago> So it's somehow C's fault that Unicode uses variable-length encoding Parent said string handling in C was elegant. My point is that it becomes fraught with (even more) issues once you throw non-English language at it. It is C's decision to handle strings in this way, and the decision of many C programmers to treat all strings as if they are just iterable character pointers. It's a recipe for bugs.
- asveikau 10y agoI am the parent you are talking about. I've made this argument many times with people: Unicode is crazy complicated in any programming language. People think that widening the char width will help - well you seem to be somebody who knows Unicode so you probably know the horrors of surrogates, combining characters vs. pre-composed diacritics, zero-width joiners, Han unification, variation selectors, BiDi... This is in no way just a C thing to deal with all that nonsense. I've not seen any language or library that I'd say does it "well" and saves individual programmers from considering the above. They all punt the issue to the programmer. I've heard (mostly here) that Swift does something different and treats glyphs as the basic unit. I haven't had a chance to look at precisely what that does. Given all the issues I've seen elsewhere I'm skeptical that someone, anyone can pull that off correctly. UTF-8 at least has one elegance (there's that word again) in the design in that you can do some "dumb" ASCII things and if your code does not know what to do with fancy unicode, you can check the high bit of any given octet and "safely" skip over it and any adjacent nonascii sequence if you don't know what it means. This may or may not be applicable to a task at hand.
- imron 10y ago> This is in no way just a C thing to deal with all that nonsense. I've not seen any language or library that I'd say does it "well" and saves individual programmers from considering the above. This is true, however even something as simple as storing the (byte) length as part of the string reduces the complexity and the likelihood for bugs. Other languages also prevent accidental buffer overruns so while they still need to deal with all the same Unicode problems you mentioned, the program likely won't crash if the programmer gets things wrong. The same is not necessarily true of C.
- Manishearth 10y agoFWIW in Rust you also tend to avoid allocations, since all string manipulation is done via slices -- safe (ptr, len) pairs. It's pretty neat. IIRC C++ is getting slices too, so it might be able to get better APIs around string manip. But I've seen decent string manip code that avoided allocations.
- burntsushi 10y ago> Using a more C way he'd really only have needed a couple of pointers on the stack. This is pretty much how it's done in Rust too via slices. For example, the standard way to split a string is to create an iterator and it won't do any allocations.