Distinct() 看不到 ToLower() 方法更改的大写字母

Distinct() doesn't see uppercase letter changed by ToLower() method

这是我的代码:

string textToEncode = File.ReadAllText(@"C:\Users\ASUS\Desktop\szyfrowanie2\TextSample.txt");
textToEncode = textToEncode.ToLower();
char[] distinctLetters = textToEncode.Distinct().ToArray();
var count = textToEncode.Distinct().Count();
Console.WriteLine("Letters used in text: \n\n");
for (int i = 0; i < count; i++)
{
    if (Equals(distinctLetters[i]," "))
    {
        Console.Write("<space>"); 
    }
    else
    {
        Console.Write(" " + distinctLetters[i] + " ");
    }
}

我想读取 .txt 文件,通过 ToLower(); 方法将其全部转为小写,但是当我想从 .txt 文件中读取所有不同的字符然后将它们写入屏幕时,它们不要出现。稍后当我使用

for (int i = 0; i < distinctLetters.Length; i++)
{
    Console.Write("Swap " + distinctLetters[i] + " with "); 

它显​​示确实已更改为小写字母但在第一个 for 循环中在屏幕上不可见的字母。我的 TextSample.txt 文件中的第一个词是 "With"。第一个循环只显示

i t h

但是当第二个循环开始时,它会询问

Swap w with

我不知道为什么。 此外,第一个循环中的 if 语句不起作用,它没有检测到 space.

我对你的代码做了一些修改,除了“修复”if 语句(因为它从来都不是真的,因为你的数组包含字符,但与字符串进行了比较(“”是一个字符串,''是a char)) 包含一个新循环,它突出显示并修复了原来的主要问题(回车 return 和新行符号,Wim 10 Brink[=17= 友善地指出了这一点] 在评论中)。我使用的字符串值只是为了演示这个问题。

string textToEncode = "abc\rdefabdg";

textToEncode = textToEncode.ToLower();

char[] distinctLetters = textToEncode.Distinct().ToArray();
var count = distinctLetters.Length;

Console.WriteLine("Letters used in text (old):");

for (int i = 0; i < count; i++)
{
    var letter = distinctLetters[i];
    if (Equals(letter, " "))
    {
         Console.Write("<space>");
    }
    else
    {
         Console.Write(distinctLetters[i]);
    }
}

Console.WriteLine();
Console.WriteLine("Letters used in text (new):");

for (int i = 0; i < count; i++)
{
   var letter = distinctLetters[i];
       
   if (!char.IsLetter(letter))
       continue;

   Console.Write(distinctLetters[i]);
}

输出为:

Letters used in text (old):

defg

Letters used in text (new):

abcdefg

我也稍微修改了你的代码:

string textToEncode = File.ReadAllText(@"C:\Users\ASUS\Desktop\szyfrowanie2\TextSample.txt").ToLower();
char[] distinctLetters = textToEncode.Distinct().ToArray();
var count = distinctLetters.Count();
Console.WriteLine("Letters used in text: \n\n");
for (int i = 0; i < count; i++)
{
    if (Equals(distinctLetters[i], ' ')) { Console.Write("<space>"); }
    else if (Equals(distinctLetters[i], '\r')) { Console.Write("<cr>"); }
    else if (Equals(distinctLetters[i], '\n')) { Console.Write("<lf>"); }
    else { Console.Write(" " + distinctLetters[i] + " "); }
}

只是一些小事。我合并了前两行,将 " " 更改为 ' ' 因此它现在比较字符,更改字符计数以使用 distinctLetters 而不是再次执行相同的 Distinct() 命令并且我 添加了两个条件 来处理回车 return 和换行。 (顺便说一句,我总是把它们混在一起。)
这现在显示了正确的结果,但也应该可以解释为什么字符丢失了!一个简单的原因,其实。 您的文本文件有一个回车 return 字符,它将使光标返回左侧。 这将导致第一个字符被 space 覆盖。 ..

因此您的代码实际上打印了“w i ...”,但随后得到了“\r”。然后它将打印 space,返回到行首并在 ' '! 上写另一个 space。然后下一个换行符将在 'w' 上打印第二个 space,移动到下一行并再次打印 space。然后打印其余部分...

很简单,不是吗?但是通过用两个额外的 if 语句捕获这两个特殊字符,它是固定的... :-) '\r' 和 '\n' 字符在控制台应用程序中经常被忽略,当它们被打印时会产生意想不到的结果。