Why does this code to replace accented chars with html codes fail to work?

2k views Asked by At

I want to replace accented chars (such as á, ñ, ¿, ¡, etc.) with the corresponding HTML codes (such as á, ñ, ¿, ¡, etc.).

For example, this line of text:

Imposible me ha sido rehusarme á las repetidas instancias que el Caballero Trelawney, el Doctor Livesey y otros muchos señores me

...should become:

Imposible me ha sido rehusarme á las repetidas instancias que el Caballero Trelawney, el Doctor Livesey y otros muchos señores me

This should be simple. I've got this code to make the attempt:

private void buttonReplaceCharsWithCodes_Click(object sender, EventArgs e)
{
    String fallName = String.Empty;
    List<String> linesModified = new List<string>();
    StreamReader file = null;

    try // finally
    {
        try // catch
        {

            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                fallName = openFileDialog1.FileName;
            }
            file = new StreamReader(fallName);
            String line;
            while ((line = file.ReadLine()) != null)
            {
                linesModified.Add(line);
            }

            progressBar1.Maximum = linesModified.Count;
            progressBar1.Value = 0;
            labelProgFeedback.Text = "Replacing accented chars with HTML codes";

            for (int i = 0; i < linesModified.Count; i++)
            {
                linesModified[i] = linesModified[i].Replace("á", "&aacute;");
                linesModified[i] = linesModified[i].Replace("Á", "&Aacute;");
                linesModified[i] = linesModified[i].Replace("é", "&eacute;");
                linesModified[i] = linesModified[i].Replace("É", "&Eacute;");
                linesModified[i] = linesModified[i].Replace("í", "&iacute;");
                linesModified[i] = linesModified[i].Replace("Í", "&Iacute;");
                linesModified[i] = linesModified[i].Replace("ñ", "&ntilde;");
                linesModified[i] = linesModified[i].Replace("Ñ", "&Ntilde;");
                linesModified[i] = linesModified[i].Replace("ó", "&oacute;");
                linesModified[i] = linesModified[i].Replace("Ó", "&Oacute;");
                linesModified[i] = linesModified[i].Replace("ú", "&uacute;");
                linesModified[i] = linesModified[i].Replace("Ú", "&Uacute;");
                linesModified[i] = linesModified[i].Replace("ü", "&uuml;");
                linesModified[i] = linesModified[i].Replace("Ü", "&Uuml;");
                linesModified[i] = linesModified[i].Replace("¿", "&iquest;");
                linesModified[i] = linesModified[i].Replace("¡", "&iexcl;");
                progressBar1.PerformStep();
            }
            progressBar1.Value = 0;
        }
        catch (Exception ex)
        {
            MessageBox.Show(String.Format("Exception {0}", ex.Message));
        }
    }
    finally
    {
        String massagedFileName = String.Format("{0}_Massaged.txt", fallName);
        File.WriteAllLines(massagedFileName, linesModified);
        file.Close();
    }

}

Unfortunately, it doesn't work. It replaces the accented chars with the "what the heck?!?" symbol (�) instead of the HTML code desired. What is required to get this to work?

UPDATE

In answer to the comments, this is the contents of the file I load:

Imposible me ha sido rehusarme á las repetidas instancias que el Caballero Trelawney, el Doctor Livesey y otros muchos señores me han hecho para que escribiese la historia circunstanciada y completa de la Isla del Tesoro. Voy, pues, á poner manos á la obra contándolo todo, desde el alfa hasta el omega, sin dejarme cosa alguna en el tintero, exceptuando la determinación geográfica de la isla, y esto tan solamente porque tengo por seguro que en ella existe todavía un tesoro no descubierto. Tomo la pluma en el año de gracia de 17-- y retrocedo hasta la época en que mi padre tenía aún la posada del "Almirante Benbow," y hasta el día en que por primera vez llegó á alojarse en ella aquel viejo marino de tez bronceada y curtida por los elementos, con su grande y visible cicatriz.

...and this is the file it saves with the replacements:

Imposible me ha sido rehusarme � las repetidas instancias que el Caballero Trelawney, el Doctor Livesey y otros muchos se�ores me han hecho para que escribiese la historia circunstanciada y completa de la Isla del Tesoro. Voy, pues, � poner manos � la obra cont�ndolo todo, desde el alfa hasta el omega, sin dejarme cosa alguna en el tintero, exceptuando la determinaci�n geogr�fica de la isla, y esto tan solamente porque tengo por seguro que en ella existe todav�a un tesoro no descubierto. Tomo la pluma en el a�o de gracia de 17-- y retrocedo hasta la �poca en que mi padre ten�a a�n la posada del "Almirante Benbow," y hasta el d�a en que por primera vez lleg� � alojarse en ella aquel viejo marino de tez bronceada y curtida por los elementos, con su grande y visible cicatriz.

IOW, the replacements are not happening - I'm just seeing the "mystery" character instead of the HTML codes.

I see the same thing at runtime when I step through the code and examine the individual lines of "linesModified" (I see �s). Better than seeing stars, I guess.

This is the process: it's a simple util where I click the button to open the (.txt) file. After processing, it saves the new version of the file to a new file.

UPDATE 2

Since it's possible to save explicitly as UTF8, I thought maybe doing so in reading the file may prove advantageous, but this:

while ((line = file.ReadLine(ASCIIEncoding.UTF8)) != null)

...doesn't compile, saying there is no overload of the ReadLine method that takes 1 argument.

2

There are 2 answers

4
AngularRat On BEST ANSWER

Only thing I can think of is specifically specifying your encoding on the file write, like:

File.WriteAllLines(massagedFileName, linesModified, Encoding.UTF8);
0
B. Clay Shannon-B. Crow Raven On

The answer by Jerome Laben here works - I just needed to change this line of code:

file = new StreamReader(fallName);

...to this:

file = new StreamReader(fallName, Encoding.Default, true);

...and now it works:

Imposible me ha sido rehusarme &aacute; las repetidas instancias que el Caballero Trelawney, el Doctor Livesey y otros muchos se&ntilde;ores me han hecho para que escribiese la historia circunstanciada y completa de la Isla del Tesoro. Voy, pues, &aacute; poner manos &aacute; la obra cont&aacute;ndolo todo, desde el alfa hasta el omega, sin dejarme cosa alguna en el tintero, exceptuando la determinaci&oacute;n geogr&aacute;fica de la isla, y esto tan solamente porque tengo por seguro que en ella existe todav&iacute;a un tesoro no descubierto. Tomo la pluma en el a&ntilde;o de gracia de 17-- y retrocedo hasta la &eacute;poca en que mi padre ten&iacute;a a&uacute;n la posada del "Almirante Benbow," y hasta el d&iacute;a en que por primera vez lleg&oacute; &aacute; alojarse en ella aquel viejo marino de tez bronceada y curtida por los elementos, con su grande y visible cicatriz.