Live data from Hacker News

A popular but wrong way to convert a string to uppercase or lowercase

devblogs.microsoft.com

191–200 of 272 posts

Re: A popular but wrong way to convert a string to uppercase or lowercase

#191
I generally just use the language-supported tolower/upper() (or similar) routines. I assume that they take things like UTF and alternative type systems into account.

I'm not sure about other languages, but Swift has pretty intense String support[0], and can go quite a long ways.

Someone actually wrote a whole book about just Swift Strings[1].

[0] https://docs.swift.org/swift-book/documentation/the-swift-pr...

[1] https://flight.school/books/strings/

Re: A popular but wrong way to convert a string to uppercase or lowercase

#192

Earlier quoted context omitted.

Those functions take and return single characters. What's missing is functions that operate on strings. You can use them in combination with std::transform(), but as the article points out, even if you're just dealing with ASCII you can easily do it wrong. I've been using C++ for over 20 years and I didn't know tolower() and toupper() were non-addressable. There's really no excuse for the library not having simple ca…

std::transform() seems like overkill when you can just iterate over the string and modify it in place. And in my opinion, tranform is way less readable than seeing a loop over some array with a single operation inside. The article talks about wstrings for good reason. If you're converting narrow strings, you don't need to be this fancy. Just loop over the string and edit it in place. If you are operating on wide stri…

> The article talks about wstrings for good reason. If you're converting narrow strings, you don't need to be this fancy. Just loop over the string and edit it in place.

Since you mention narrow strings in the context of wstring, just to make sure... you can't convert a UTF-8 std::string character by character, in-place (in case that's what you meant).

7-bit ASCII code points are fine, but outside that it's not guaranteed that one UTF-8 byte converts into exactly one UTF-8 byte when converting case.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#193

In gamedev there is simple rule: don't try to do any of that. If it is text game needs to show to user then every version of the text that is needed is a translated text. Programmer will never know if context or locale will need word order changes or anything complicated. Just trust the translation team. If text is coming from user - then change design until its not needed to 'convert'. There are major issues just to…

I don’t think you can say this is universally known in ‘game dev’. In fact just last week I stumbled using the UI in a game that let me enter a name for something, which it then displayed in uppercase.

Game UI is the place I’d expect to most likely come across horrific abuses of localization precisely because game UI is such a cobbled together layer of hacks on hacks.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#195

Earlier quoted context omitted.

It’s been 30 years. Unicode predates C++98. Java saw the writing on the wall. There’s no excuse.

Java ended up picking UCS-2 and getting screwed.

Pretty much all Unicode early adopters went for 16-bit chars. Qt and Win32 API are another pair.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#196
post #187

Earlier quoted context omitted.

> In gamedev there is simple rule: don't try to do any of that. I am not in gamedev, but I frequently have to develop middleware that takes in user entered data and formats it in a way that will import into a 3rd party system without errors. And that sometimes means changing the case on strings. In my experience as a developer, this is very very common requirement. Luckily I am not forced to use a low level language…

The problem is that such third-party requirements are usually wrong . Two decades ago some developer probably went "Yeah, obviously all names start with capital letters!", not realizing that there are in fact plenty of names which start with a lowercase letter. So they added an input validation test which checks for capitals, which meant everyone feeding that system had to format their data. A whole ecosystem grew ar…

It’s a lossy operation, but it does work. By this logic jpeg and mpeg don’t work either. But were watching them videos daily.

Yes we can simply ToUpper(). We just can’t ToUpper().ToLower(), but that’s useless cause we have the original string if we need it and fine if we don’t need it.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#197

The key takeaway here is that you can't correctly process a string if you don't what language it's in. That includes variants of the same language with different rules, eg en-US and en-UK or es-MX and es-ES. If you are handling multilingual text the locale is mandatory metadata.

Language is just part of the problem. Unicode lets you store text as entered, but what you do with that text completely depends on what your problem domain is. When you're writing software to validate that the name on someone's ID matches that on a ticket, you're probably going to normalise that name to your (customer's) locale rather than render each name in the locale it was originally written in. As long as you keep your locale settings consistent and don't do bad stuff like "iterate over characters and individually transform them", you're probably fine, unless your problem domain calls for something else.

If you're printing a name, you're probably printing the name for the current user, not for the person who entered it at some point. If you're going to try to convert back like that, you also need to store a timestamp with every string in case a language changes its rules (such as permitting ẞ instead of SS when capitalising ß). And even then, someone might intend to use the new spelling rules, or they might not, who knows!

This article probably boils down to "programmers don't realise graphemes aren't characters and characters aren't bytes even though they usually are in US English". The core problem, "text processing looks easy as long as you only look at your own language", is one that doesn't just affect computers.

Your best bet is to just avoid the entire problem by not processing input further than basic input sanitisation, such as removing whitespace prefixes/suffixes and maybe stripping out invalid unicode so it can't be used as a weird stored attack.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#198

Earlier quoted context omitted.

In Rust, the APIs are clear if they're ASCII only or unicode aware. https://doc.rust-lang.org/stable/std/primitive.str.html#meth... > ‘Lowercase’ is defined according to the terms of the Unicode Derived Core Property Lowercase. https://doc.rust-lang.org/stable/std/primitive.str.html#meth... > ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are unchanged. Now, "perfectly" is very strong. For e…

> 99% of Unicode stuff Does that include context-dependent conversion rules like o'reilly -> O'Reilly?

Sort of, see the Greek example elsewhere in this thread. I don’t think that specific situation is part of Unicode though.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#199

Earlier quoted context omitted.

Java ended up picking UCS-2 and getting screwed.

Pretty much all Unicode early adopters went for 16-bit chars. Qt and Win32 API are another pair.

Indeed, ICU as well, and then they all moved to UTF-16, which, again. in the long term lost to UTF-8. My point is that committing on a specific Unicode design 30 years ago was not, in retrospect, necessarily a good idea.

By not committing to UCS-2 early C++ left the road open to UTF-8. I'll concede that UTF8 has risen as the clear winner for more than a decade and C++ is well past the point that it should have at least basic builtin support. The problem is that there is at least one important C++ platform that only very recently added full support for the encoding in their native API.

Re: A popular but wrong way to convert a string to uppercase or lowercase

#200

Earlier quoted context omitted.

I mean, I already know some Unicode internals and linguistics (since I developed a language-specific compression algorithm back in the day), but I have never seen a single character requiring four bytes (and I know Emoji chaining for skin color, etc.). So, seeing this just moved the complexity of Unicode one notch up in my head, and I respect the guys who designed and made it work. It was not whining or complaining o…

Cuneiform codepoints are 17 bits long. If you're using UTF-16 you'll need two code units to represent a character.

you also need two UTF16 code units for plain emojis.
Post reply on HN