none
Problema al reemplazar un carácter RRS feed

  • Pregunta

  • Buenos dias, he escrito un codigo que me permite analizar una linea de un archivo de texto y reemplazar algunos caracteres (Ñ,ñ,#,%,"), el problema es que el caracter con el que reemplazo es espacio, y esto medio funciona; El reemplazo quita el caracter pero no agrega el espacio.

    Ej:

    Queda Asi:

    Pedro Nuñes -> Pedro Nues

    Y quiero lograr esto:

    Pedro Nuñes -> Pedro Nu es

    Mi codigo: 

    public static string CorrectLine(string oldline)
    {
    	string customerInfoA, customerInfoB, customerInfoC, restOfDataA, restOfDataB;
    
    	restOfDataA = oldline.Substring(0, 23);//Datos iniciales no es necesario hacer nada con ellos
    	customerInfoA = oldline.Substring(23, 30).Replace(",", " ").Replace("Ñ", " ").Replace("ñ", " ").Replace("#", " ").Replace("%", " ").Replace("\"", " "); //Campo Cliente 1
    	customerInfoB = oldline.Substring(55, 30).Replace(",", " ").Replace("Ñ", " ").Replace("ñ", " ").Replace("#", " ").Replace("%", " ").Replace("\"", " "); //Campo Cliente 2
    	customerInfoC = oldline.Substring(86, 26).Replace(",", " ").Replace("Ñ", " ").Replace("ñ", " ").Replace("#", " ").Replace("%", " ").Replace("\"", " "); //Campo Cliente 3
    	restOfDataB = oldline.Substring(112);//Datos finales no es necesario hacer nada con ellos
    
    	return restOfDataA + customerInfoA + ",," + customerInfoB + "," + customerInfoC + restOfDataB;
    }

    Cabe aclarar que la aplicación es un servicio de Windows para .NET 2.0

    Aprovecho y añado el codigo que escribe el archivo txt (Por si acaso):

    public static bool Create(List<string> src, string dest)
    {
    	if (src.Count >= 0)
    	{
    		List<string> removeData = new List<string>(src);		
    		using (FileStream fs = new FileStream(dest, FileMode.Create, FileAccess.Write, FileShare.Read))
    		{
    			using (StreamWriter sw = new StreamWriter(fs))
    			{
    				foreach (string data in src)
    				{
    					sw.WriteLine(data);
                        removeData.Remove(data);
    				}
    			}
    		}
    
    		int tempvalue = removeData.Count;
    		src.Clear();
    		removeData = null;
    
    		return !(tempvalue > 0) && (new FileInfo(dest).Exists);
    	}
    	else
    		return false;
    }
    PD: Ya intenté con caracteres (......Replace('Ñ', ' '))

    jueves, 17 de enero de 2019 15:46

Respuestas

  •  el server no está en español (está en inglés) y no se si funcionará el '1252'

    Sí, en inglés sí que debería funcionar el 1252 (y también en francés, italiano, etc.). En cambio te fallaría si el archivo se hubiese generado (por ejemplo) en un Windows en árabe o en griego. Observa que lo importante es cuál es el juego de caracteres que se utilizó al generar el archivo, ya que tienes que leerlo aplicando el mismo juego de caracteres. No tiene importancia cuál sea el juego nativo del Windows desde el que lees o grabas.

    viernes, 18 de enero de 2019 12:09
    Moderador
  • note que el archivo original es ANSI y el resultado es UTF-8 no se si eso es lo que causa que las 'ñ' se vean así

    Sí, eso será un auténtico desastre. Las Ñ en ANSI ocupan un único byte, pero en UTF-8 requieren 3 bytes. Quedará fatal si está grabado en un formato y lo interpretas como el otro.

    Si estás leyendo desde un archivo, asegúrate de que pasas el parámetro opcional System.Text.Encoding con el valor correcto (por ejemplo, 1252 si es el ANSI de Windows en Español). Si no estás leyendo de un fichero sino de otro sitio, trae los caracteres a un array de bytes (no a un String) y luego pásalos del array de bytes a un string usando el GetString del Encoding:

    string cadena = System.Text.Encoding.GetEncoding(1252).GetString(arrayDeBytes);

    jueves, 17 de enero de 2019 21:13
    Moderador

Todas las respuestas

  • El Replace funciona perfectamente con los espacios, con toda seguridad. Lo he usado muchas veces.

    Sigue la ejecución con el debugger y examina las variables justo después de haber ejecutado el Replace, y verás cómo contienen los espacios esperados. Si más adelante llega a algún punto del programa en el que no aparecen los espacios, entonces tiene que haber alguna otra cosa entre medias que los esté suprimiendo. Sigue la ejecución paso a paso con el debugger examinando las variables en cada punto hasta que encuentres el sitio exacto en el que se pierden los espacios.

    jueves, 17 de enero de 2019 17:30
    Moderador
  • Bueno, disculpame pero no se como depurar un servicio de windows.

    Cuando le doy a la opcion de depurar me dice que no se puede depurar un servicio de windows


    El servicio esta montado en un Windows Server 2003 me parecio que aclarar eso puede ayudar, porque en windows 7 no me muestra tampoco el espacio en su lugar me muestra un cuadrado donde deberia estar colocando el espacio

    jueves, 17 de enero de 2019 18:43
  •  no me muestra tampoco el espacio en su lugar me muestra un cuadrado donde deberia estar colocando el espacio

    Ah, eso es significativo. Indica que en realidad no has tecleado un espacio sino que has tecleado algún carácter Unicode que aparenta ser un espacio en el juego de caracteres en el que lo has tecleado, pero al visualizarlo no existe en el font que usas para visualizar y por eso lo muestra como un cuadrado.

    no se como depurar un servicio de windows

    Hay varias opciones. Una es poner el servicio en marcha, y después abrir el fuente en Visual Studio y desde el menú Depurar usar la opción de Conectar a Proceso (Attach en inglés) y conectarse al servicio que está en ejecución. Otra opción es modificar el Main del servicio para que acepte un parámetro tal que cuando se lo pases en la línea de comandos arranque el OnStart directamente como aplicación de consola en lugar de hacer el Run del Service. Eso permite depurarlo con normalidad como aplicación de consola poniendo ese parámetro al iniciar desde Visual Studio. Otra es meter el código principal en una DLL y referenciarla desde dos aplicaciones: una que sea el propio servicio y otra que sea una pequeña aplicación de consola, y usar esta última para depurar.

    jueves, 17 de enero de 2019 19:08
    Moderador
  • Muchas gracias, aprendí a depurar el servicio, ahora por otro lado, me di cuenta que el programa no detecta todas las 'Ñ', de hecho te diria que no creo que las reemplace, ya que puse un punto de control a las correcciones que hacia, pero nunca entro un registro con (y si los hay y muchos) 'Ñ', si no los que vienen con #, %, ", y adicionalmente note que el archivo original es ANSI y el resultado es UTF-8 no se si eso es lo que causa que las 'ñ' se vean así

    Para referencia (Metodo que evalua si se cumplen los requerimientos): 

    //iData Contiene los datos leidos por un File.ReadAllLines("archivo origen")
    
    if (!string.IsNullOrEmpty(iData[i].Trim()) && !Analyzer.IsLineMeetsRequirements(iData[i], FileDelimiter == '\0' ? ',' : FileDelimiter, FileFields == -1 ? 39 : FileFields))
    {
         eData = eData ?? new List<string>();
         eData.Add(z = "Linea " + (i + 1).ToString("0000") + ": " + iData[i]);
         iData[i] = Analyzer.CorrectLine(iData[i]);
    
    }
    
    //Metodo que indica si la liena cumple los requerimientos (no contenga ñ,#,%,")
    
    public static bool IsLineMeetsRequirements(string line, char delimiterFile, int InfileFields) => line.Split(delimiterFile).Length == InfileFields && !line.Contains("Ñ") && !line.Contains("ñ") && !line.Contains("#") && !line.Contains("%") && !line.Contains("\"");
    No se si mi logica este mal, pero creo que no esta detectando las ñ pero esta bien definido el codigo

    jueves, 17 de enero de 2019 19:53
  • note que el archivo original es ANSI y el resultado es UTF-8 no se si eso es lo que causa que las 'ñ' se vean así

    Sí, eso será un auténtico desastre. Las Ñ en ANSI ocupan un único byte, pero en UTF-8 requieren 3 bytes. Quedará fatal si está grabado en un formato y lo interpretas como el otro.

    Si estás leyendo desde un archivo, asegúrate de que pasas el parámetro opcional System.Text.Encoding con el valor correcto (por ejemplo, 1252 si es el ANSI de Windows en Español). Si no estás leyendo de un fichero sino de otro sitio, trae los caracteres a un array de bytes (no a un String) y luego pásalos del array de bytes a un string usando el GetString del Encoding:

    string cadena = System.Text.Encoding.GetEncoding(1252).GetString(arrayDeBytes);

    jueves, 17 de enero de 2019 21:13
    Moderador
  • Hola:

    using System;
    
    class stringReplace1 {
        public static void Main() {
            String str = "1 2 3 4 5 6 7 8 9";
            Console.WriteLine("Original string: \"{0}\"", str);
            Console.WriteLine("CSV string:      \"{0}\"", str.Replace(' ', ','));
        }
    }
    //
    // This example produces the following output:
    // Original string: "1 2 3 4 5 6 7 8 9"
    // CSV string:      "1,2,3,4,5,6,7,8,9"
    //

    String.Replace Method.

    https://docs.microsoft.com/es-es/dotnet/api/system.string.replace?view=netframework-4.7.2

    Saludos.


    http://electronica-pic.blogspot.com

    viernes, 18 de enero de 2019 0:26
  • Quedará fatal si está grabado en un formato y lo interpretas como el otro.

    Efectivamente, esto al parecer era el problema.

    Si estás leyendo desde un archivo, asegúrate de que pasas el parámetro opcional System.Text.Encoding con el valor correcto (por ejemplo, 1252 si es el ANSI de Windows en Español)

    Esta es la solución que funcionó, al menos en windows 7, dejame probar montarlo en server 2003 y te digo, aunque el server no está en español (está en inglés) y no se si funcionará el '1252'

    string[] t = File.ReadAllLines(filepath, Encoding.GetEncoding(1252));

    Así quedo la linea que lee el archivo.

    y la que escribe:

    public static bool Create(List<string> src, string dest)
    {
    	List<string> removeData = new List<string>(src);
    
    	if (src.Count >= 0)
    	{
    		using (FileStream fs = new FileStream(dest, FileMode.Create, FileAccess.Write, FileShare.Read))
    		{
    			using (StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding(1252)))
    			{
    				foreach (string data in src)
    				{
    					sw.WriteLine(data);
    					removeData.Remove(data);
    				}
    			}
    		}
    
            int tempvalue = removeData.Count;
            src.Clear();
            removeData = null;
    
            return !(tempvalue > 0) && (new FileInfo(dest).Exists);
    	}
        else
    		return false;
    }

    viernes, 18 de enero de 2019 11:54
  • Muchas gracias por la respuesta, pero ya no creo que sea problema del 'replace' sino de la decodificación del texto, el replace si funciona, pero no encuentra el caracter que le indico por que no es representado igual en ANSI que en UTF8.
    viernes, 18 de enero de 2019 11:58
  •  el server no está en español (está en inglés) y no se si funcionará el '1252'

    Sí, en inglés sí que debería funcionar el 1252 (y también en francés, italiano, etc.). En cambio te fallaría si el archivo se hubiese generado (por ejemplo) en un Windows en árabe o en griego. Observa que lo importante es cuál es el juego de caracteres que se utilizó al generar el archivo, ya que tienes que leerlo aplicando el mismo juego de caracteres. No tiene importancia cuál sea el juego nativo del Windows desde el que lees o grabas.

    viernes, 18 de enero de 2019 12:09
    Moderador
  • Está funcionando de maravilla en el servidor, lo que aprendi de esta pregunta fue mas de lo esperado, muchisimas gracias
    viernes, 18 de enero de 2019 19:01