3

Could you have a look at my sample?

enter image description here

This result produces from the following example:

var str = @"VIENNA IS A VERY BEAUTIFUL CAPITAL CITY.";
var title = new CultureInfo("en-US", false).TextInfo.ToTitleCase(str.ToLower());
MessageBox.Show(title);

Because the language of the program is Turkish. I would like to draw your attention to the dotted letter I. But we all know that the right way should look like this:

Vienna Is A Very Beautiful Capital City.

How can I get the true result?

Habip Oğuz
  • 921
  • 5
  • 17
  • 1
    @LasseV.Karlsen The lower-case `i`'s in the screenshot are dotless (`ı`). Turkish has dotted and dotless `i`'s, and the dotless `ı` capitalises to `I`, whereas the dotted `i` capitalises to `İ`. This [famously broke PHP](https://bugs.php.net/bug.php?id=18556) – canton7 May 28 '21 at 10:35
  • 6
    "Because the language of the program is Turkish". Then why did you specify en-US only for the ToTitleCase function? What about `str.ToLower()`? – Lasse V. Karlsen May 28 '21 at 10:36
  • @LasseV.Karlsen - The correct output should be: `Vienna Is A Very Beautiful Capital City.` But he codes produce without dotted like this: V`ı`enna Is A Very Beaut`ı`ful Cap`ı`tal C`ı`ty. – Habip Oğuz May 28 '21 at 10:37
  • Yes, I got it when I reread the question. – Lasse V. Karlsen May 28 '21 at 10:37
  • 2
    @HabipOğuz You need to use ToLower before... ["*Converts the specified string to title case (except for words that are entirely in uppercase, which are considered to be acronyms).*"](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.textinfo.totitlecase) –  May 28 '21 at 10:39
  • 1
    As usual, debugging your program pinpoints the problem straight away. [It's easy to see](https://dotnetfiddle.net/INJJ2f) that the ToLower call produces `vıenna ıs a very beautıful capıtal cıty` – canton7 May 28 '21 at 10:41
  • @LasseV.Karlsen said Then why did you specify en-US only for the ToTitleCase function? Because I am coding a program that archives law articles. Most of the articles are in Turkish but there are also articles in English and German and I want to save them properly in the database. – Habip Oğuz May 28 '21 at 10:44

2 Answers2

4

string.ToLower has an overload that takes a CultureInfo. (Link)

Try something like

var culture = new CultureInfo("en-US", false);
var title = culture.TextInfo.ToTitleCase(str.ToLower(culture));
TanvirArjel
  • 30,049
  • 14
  • 78
  • 114
Jens
  • 25,229
  • 9
  • 75
  • 117
  • @HabipOğuz It's not that `ToLower` overrides `CultureInfo`, it's that `ToLower` just uses your program's `CultureInfo` unless you specify one explicitly, and your program's `CultureInfo` is Turkish – canton7 May 28 '21 at 10:42
  • 1
    @HabipOğuz: i guess you mean _string.ToLower is overloaded to take a culture_ – Tim Schmelter May 28 '21 at 10:43
3

If you want to use the US culture to perform casing, you need to do so consistently. Instead, you're currently lower-casing the string in the current culture, which is causing the problem.

Instead, use the same TextInfo for both the lower-casing and title-casing operations:

sing System;
using System.Globalization;

class Program
{
    static void Main()
    {
        CultureInfo.CurrentCulture = new CultureInfo("tr-TR");
        var text = "VIENNA IS A VERY BEAUTIFUL CAPITAL CITY.";
        
        // Original code in the question
        var title1 = new CultureInfo("en-US", false).TextInfo.ToTitleCase(text.ToLower());
        Console.WriteLine(title1); // Contains Turkish "i" characters

        // Corrected code
        var textInfo = new CultureInfo("en-US", false).TextInfo;
        var lower = textInfo.ToLower(text);
        var title2 = textInfo.ToTitleCase(lower);
        Console.WriteLine(title2); // Correct output
    }
}

(This is broadly equivalent to Jens' answer, but I prefer to use TextInfo for both operations if you're using it for either, just for consistency.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194