2012-08-24 49 views
3

我需要理解字符集和編碼權。有人可以指出我在處理C#中的不同字符集時寫得很好嗎?在C中處理非英文字符#

這裏是我現在面臨的問題之一 -

 using (StreamReader reader = new StreamReader("input.txt")) 
     using (StreamWriter writer = new StreamWriter("output.txt") 
     { 
      while (!reader.EndOfStream) 
      { 
       writer.WriteLine(reader.ReadLine()); 
      } 
     } 

這個簡單的代碼片段並不總是保持編碼 -

例如 -

Aukéna輸入變成Auk�在輸出。

回答

5

你只是有一個編碼問題。你必須記住,你真正閱讀的是一串比特。你必須告訴你的程序如何正確解釋這些位。

要解決您的問題,只需使用編碼的構造函數,並將其設置爲您的文本使用的任何編碼。

http://msdn.microsoft.com/en-us/library/ms143456.aspx

http://msdn.microsoft.com/en-us/library/3aadshsx.aspx

+0

之前我在創建編寫器時嘗試過使用reader.CurrentEncoding,但那不起作用。現在我將輸入文件保存爲UTF8格式,並且使用Encoding.UTF8代替讀寫器,這似乎毫無問題地工作。謝謝! –

2

讀取文件時,我想,你應該知道哪些編碼文件了。否則,您可能很容易無法正確讀取它。

當你知道一個文件的編碼,可以執行以下操作:

 using (StreamReader reader = new StreamReader("input.txt", Encoding.GetEncoding(1251))) 
     using (StreamWriter writer = new StreamWriter("output.txt", false, Encoding.GetEncoding(1251))) 
     { 
      while (!reader.EndOfStream) 
      { 
       writer.WriteLine(reader.ReadLine()); 
      } 
     } 

另一個問題來了,如果你想改變一個文件的原始編碼。

下面的文章可以給你一個什麼樣的編碼是一個良好的基礎: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

這是一個鏈接MSDN文章,從中你可以開始: Encoding Class

2

StreamReader.ReadLine() attemps讀取文件使用UTF編碼。如果這不是您的文件使用的格式,StreamReader將無法正確讀取字符。

This article詳細的問題,並建議通過構造這個編碼System.Text.Encoding.Default

0

您可以隨時創建自己的解析器。我使用的是:

`var ANSI =(Encoding)Encoding.GetEncoding(1252).Clone();

ANSI.EncoderFallback = new EncoderReplacementFallback(string.Empty);` 

這樣做的第一個行創建的Win-1252編碼的克隆(我處理與Win-1252工程數據庫,你可能想使用UTF-8或ASCII)。第二行 - 解析字符時 - 如果沒有與原始字符相同的結果,則返回空字符串。

在此之後,您最好過濾掉所有命令字符(根據您的需要,不包括製表符,空格,換行符和回車符)。

下面是我的個人編碼解析器,我設置了它來糾正數據進入我們的數據庫。

private string RetainOnlyPrintableCharacters(char c) 
{ 
//even if the character comes from a different codepage altogether, 
//if the character exists in 1252 it will be returned in 1252 format. 
    var ansiBytes = _ansiEncoding.GetBytes(new char[] {c}); 

    if (ansiBytes.Any()) 
    { 
     if (ansiBytes.First().In(_printableCharacters)) 
     { 
      return _ansiEncoding.GetString(ansiBytes); 
     } 
    } 
    return string.Empty; 
} 

_ansiEncoding來自var ANSI =(Encoding)Encoding.GetEncoding(1252).Clone();設置故障預置值

如果ansiBytes不爲空,則意味着有一個編碼可用於傳入的特定字符,因此將它與所有可打印字符的列表進行比較,如果它存在 - 它是一個可接受的人物如此返回。