2009-01-31 7 views
11

Ich habe ein String-ObjektWie konvertiert man eine Zeichenkette von utf8 nach ASCII (single byte) in C#?

"mit mehreren Zeichen und sogar Sonderzeichen"

I

UTF8Encoding utf8 = new UTF8Encoding(); 
ASCIIEncoding ascii = new ASCIIEncoding(); 

Objekte zu verwenden, um versuche diese Zeichenfolge in ASCII zu konvertieren. Darf ich jemanden bitten, etwas Licht in diese einfache Aufgabe zu bringen, nämlich meinen Nachmittag zu jagen?

EDIT 1: Wir versuchen, Sonderzeichen wie einige der speziellen Windows Apostrophe loszuwerden. Der Code, den ich als Antwort unten gepostet habe, kümmert sich nicht darum. Grundsätzlich

O'Brian wird O? Brian werden. wo ist einer der speziellen Apostrophe

+0

Beachten Sie, dass, wenn Sie Zeichen mit Akzent mit ihren unbetonten Äquivalente ersetzen möchten, können Sie str.Normalize (NormalizationForm.FormKD) – yoyo

Antwort

19

Dies war als Antwort auf Ihre andere Frage, die aussieht wie es gelöscht wurde .... der Punkt steht immer noch.

Sieht aus wie ein classic Unicode to ASCII issue. Der Trick wäre, zu finden, wo es geschieht.

.NET funktioniert gut mit Unicode, unter der Annahme it's told it's Unicode zu beginnen (oder Links auf der Standardeinstellung).

Meine erraten ist, dass Ihre empfangende App nicht damit umgehen kann. Also, würde ich wahrscheinlich verwenden, um die ASCIIEncoderwith ein EncoderReplacementFallback mit String.Empty:

using System.Text; 

string inputString = GetInput(); 
var encoder = ASCIIEncoding.GetEncoder(); 
encoder.Fallback = new EncoderReplacementFallback(string.Empty); 

byte[] bAsciiString = encoder.GetBytes(inputString); 

// Do something with bytes... 
// can write to a file as is 
File.WriteAllBytes(FILE_NAME, bAsciiString); 
// or turn back into a "clean" string 
string cleanString = ASCIIEncoding.GetString(bAsciiString); 
// since the offending bytes have been removed, can use default encoding as well 
Assert.AreEqual(cleanString, Default.GetString(bAsciiString)); 

Natürlich in den alten Tagen, wir würden nur wenn Schleife und entfernen Sie alle Zeichen greater than 127 ... na ja, die der wir zumindest in den USA. ;)

+4

Danke, es hat perfekt funktioniert. Ich musste nur eine kleine Änderung vornehmen. Encoding encoder = ASCIIEncoding.GetEncoding ("us-ascii", neuer EncoderReplacementFallback (string.Empty), new DecoderExceptionFallback()); – Geo

+0

+1 für EncoderReplacementFallback - davon hatte ich noch nie gehört. Liebe es. –

+0

'EncoderReplacementFallback' mit einem Fragezeichen ist der Standardwert. In diesem Fall scheint eine "bessere Verlustquote" wünschenswert. Ein Ausnahmefallbackback ist nützlich, wenn verlustbehaftet nicht tolerierbar ist (wobei IMHO der Standardwert sein sollte). –

12

Ich konnte es herausfinden. Falls jemand will unter dem Code wissen, die für mich gearbeitet:

ASCIIEncoding ascii = new ASCIIEncoding(); 
byte[] byteArray = Encoding.UTF8.GetBytes(sOriginal); 
byte[] asciiArray = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray); 
string finalString = ascii.GetString(asciiArray); 

Lassen Sie mich wissen, ob es einen einfacheren Weg ist es o tun.

+0

unter Hinweis darauf, dass es sich lohnt verwenden können, wenn die Zeichenfolge Zeichen enthält, die nicht in ASCII dargestellt werden kann, Es wird nicht die gleiche Zeichenfolge nach der Konvertierung sein. Es fehlen diese Zeichen oder es wird möglicherweise verstümmelt, je nachdem, wie Encoding.Convert funktioniert (was ich nicht weiß). –

+0

Eigentlich habe ich gerade ein paar Szenarien getestet und was du sagst ist wahr. Kannst du diese Einschränkung überwinden? Zum Beispiel, wenn ich eines der speziellen Apostrophe habe, um es durch das gemeinsame zu ersetzen. – Geo

7

Für alle, die Extension-Methoden mögen, tut dies der Trick für uns.

using System.Text; 

namespace System 
{ 
    public static class StringExtension 
    { 
     private static readonly ASCIIEncoding asciiEncoding = new ASCIIEncoding(); 

     public static string ToAscii(this string dirty) 
     { 
      byte[] bytes = asciiEncoding.GetBytes(dirty); 
      string clean = asciiEncoding.GetString(bytes); 
      return clean; 
     } 
    } 
} 

(System-Namespace, so dass es ziemlich automatisch für alle unsere Strings verfügbar ist.)

5

Basierend auf Mark Antwort oben (und Geo Kommentar), Ich habe eine zwei Liner-Version alle ASCII Ausnahme Fälle entfernen von einer Schnur. Für Leute, die nach dieser Antwort suchen (wie ich es getan habe).

1

Wenn Sie eine 8-Bit-Darstellung von Zeichen wünschen, die in vielen Kodierungen verwendet wurden, kann Ihnen dies helfen.

Sie müssen die Variable targetEncoding in die von Ihnen gewünschte Kodierung ändern.

Encoding targetEncoding = Encoding.GetEncoding(874); // Your target encoding 
Encoding utf8 = Encoding.UTF8; 

var stringBytes = utf8.GetBytes(Name); 
var stringTargetBytes = Encoding.Convert(utf8, targetEncoding, stringBytes); 
var ascii8BitRepresentAsCsString = Encoding.GetEncoding("Latin1").GetString(stringTargetBytes);