![]() |
String, AnsiString, Ascii y la madre de Embarcadero
Buenas a todos.
No se si os habrá pasado a vosotros, pero a mi me tiene frito:mad: y no encuentro solución (de momento), además, creo que la culpa es de mis padres (R.I.P.) y de la madre que pario a los de Embarcadero. El caso es que mi nombre es César, si, con acento en la letra E y lógicamente lo uso como tal (se que algún forero es muy crítico con los acentos:D) ¿Que me pasa? que si mando una cadena con mi nombre a ... digamos un socket no se envia "César" sino "CÚsar', ¿Comorrrr:eek:? Investigo, investigo, mucho, pero mucho. Y la conclusión a la que he llegado es la siguiente: Que necesito enviar la siguiente secuencia ASCII (67, 130, 115, 97, 114) osea "César" y que me pasa ... que sale (67, 233, 115, 97, 114) osea "CÙsar". Da igual como defina la cadena, ShortString, AnsiString, String, UnicodeString, WideString, array of char, array of byte, array of word, siempre que miro el carácter me devuelve 233 en vez de 130. ¿Se os ocurre como solucionarlo? Gracias por adelantado. |
cesarsoftware,
Cita:
Revisa este código: El código anterior en Delphi 7 sobre Windows 7 Professional x32, representa la secuencia (C, é, s, a, r) en valores ordinales (67, 233, 115, 97, 114) y la secuencia (C,Ù,s,a,r) en valores ordinales (67, 218, 115, 97, 114) según lo esperado, Pregunto: ¿Las secuencias de carácteres del código anterior se representan correctamente en sus valores ordinales en tu sistema?. Revisa este link: Cita:
Nelson. |
Gracias Nelson por contestar, luego comprobaré el código que planteas, pero creo que por lo que dices en nuestra máquina/windows es asi, pero no en el resto.
Es decir, cuando un telnet remoto conecta con mi aplicación, recibe ese ascii 233 en vez del 130 que el espera, no se mi explico bien, en la tabla ascii standar (la de toda la vida) para la E acentuada el carácter es 130 no 233, ¿Como puedo hacer que use la tabla "normal" Como por ejemplo esta tabla http://www.elcodigoascii.com.ar/ |
Cita:
"There are several different variations of the 8-bit ASCII table. The table below is according to ISO 8859-1, also called ISO Latin-1. Codes 129-159 contain the Microsoft® Windows Latin-1 extended characters." ¿Como sabemos que tabla usar? |
cesarsoftware,
Cita:
1- ¿En que versión de Delphi esta desarrollada tu aplicación?. 2- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que envía la secuencia?. 3- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que recibe la secuencia?. Espero sea útil :) Nelson. |
Creo, (y supongo que es evidente) que el problema se da por la transformación de un texto desde UTF8 a ASCII... estas transportando, cargando un texto que VES en ASCII pero que te ha sido entregado en otro formato... tu lo recibes en ASCII y lo tratas como ASCII... y todo tu codigo está pensado en ASCII...
A mi me sucedia algo parecido, al crear un documento de TEXTO en Notepad++... Cuando lo leia en Delphi con un TStringList me mostraba éstos carateres extraños...
lo que sucedía era que el archivo se estaba guardando en UTF8.. para esto Delphi da una solución
Y listo..!! A pesar que las variables String aceptan por defecto (ahora) carcateres unicode, el TStringList le estaba enviando algo que creia era ASCII... saludo, |
Cita:
2. Windows 7 64 (España, Internacional) 3. Ni idea, puede ser cualquiera, incluso linux, el cliente remoto es eso, un cliente remoto, yo creo un servidor TCP y a mi aplicación se le hacen consultas, por ejemplo (Lista de usuarios, Nombres de máquinas, estado de máquina tal o cual, etc) por eso, la mayoria (o todos) esperan una secuencia ASCII |
Cita:
Por cierto, uso asnsistring porque cada caracter es de 8 bit, si uso string cada carácter es de 16 bit, que ya me las he tenido que ver con Delphi 2010 por este tema.
|
Es esta función no puedo selecionar una tabla de conversión, necesito enviar en ASCII y no te digo nada cuando el cliente remoto es un control numérico CNC de hace 20 años:rolleyes: que vete tu a saber que SO lleva sino es un SO propietario, lo que si se es que lo normal es que esperen caracteres ASCII.
He intentado convertir la cadena: ansistring recibida a otro tipo como decia al principio de este post para tampoco he solucionado el tema. ¿Como puedo convertir la cadena recibida en una cadena ASCII? String, ShortString, AnsiString, UnicodeString, WideString parece que son UTF8 en Delphi 2010. Aunque pensandolo bien, si la cadena ya se ha generado en UTF8 no voy a poder convertirla nunca, debo crear la cadena original en ASCII ¿Como se hace esto? no he visto nada en la ayuda de Delphi 2010 Thanks |
cesarsoftware,
Cita:
1- Sería conveniente saber cuales son las características del cliente remoto que presenta el problema mencionado en el Msg #1, quizás con mayor información podamos acotar el problema de forma más precisa. 2- ¿Has probado el tipo de dato UTF8String y la función de conversión Utf8ToAnsi?, la idea es manejar los datos a enviar en el Servidor como UTF8String y convertirlos a ASCII por medio de Utf8ToAnsi al momento del envío. Revisa esta información: Cita:
4- Revisa este código: El código anterior convierte un String a un AnsiString con un CodePage específico, quizás puedas probar enviando los datos como CodePage 437. Revisa este link: Cita:
1- ¿El problema se presenta con más de un cliente remoto?. 2- ¿Hay clientes remotos con los que funciona bien la transferencia?. 3- ¿Has considerado normalizar todos los datos eliminado los caracteres acentuados por sus correspondientes sin acento?. Espero sea útil :) Nelson. |
cesarsoftware,
Cita:
Cita:
El código anterior en Delphi 2010, define un tipo de string asociado a un codepage particular, lo cual permitirá enviar la información del Servidor al Cliente Remoto en función del formato requerido en el Msg #1 por medio del CodePage 437, según se muestra en la siguiente imagen: ![]() Revisa este link: Cita:
Nelson. |
Buenos días nelson.
Perdona por no haber respondido antes, tu esfuerzo se merece una pronta respuesta, pero por suerte he estado todas la semana muy liado con unas ventas nuevas:D Tus respuestas tienen toda la pinta de ser lo que necesito, usar el codepage 437 porque soy yo el que emite un codigo incorrecto para lo esperado 233 en vez de 130. No te tenido tiempo de implementar la función, espero poder hacerlo esta tarde y te comento. Gracias. |
Cita:
2. No, en ninguno Es decir, yo emito mal el carácter como te comentaba en el post anterior. 3. Imposible, es el usuario el que define los nombres, el ejemplo de "César" es porque detecte el fallo usando mi propio nombre como ejemplo. Gracias de nuevo. |
Cita:
|
cesarsoftware,
Cita:
Espero sea útil :) Nelson. |
Buenos días Nelson.
Implemente la función ChangeCodePage de forma que si al objeto TServidorSocket de le indica un codepage entonces la usa, Y lo curioso es que en la aplicación que me hacia falta funciono:D Gracias. Pero al ser un objeto que uso en otras aplicaciones, probar en otra con algunos mensajes como "Máquina no encontrada" y no funciona:confused: ¿Se puede especificar un codepage para toda la aplicación? He visto en propiedades del proyecto "Compiling" y "Resource compiling" el valor para codepage, he puesto en ambos casos 437 y no noto diferencia, también está la opción "Version info" la posiblididad de definir el "Locale ID" pero tampoco veo resultado. Asi que de momento mejor que antes ya estoy. Gracias. |
Tambien en probado con esto
Y la uso asi
Y al pasar por la funcion del mensaje anterior, he probado a que convierta a 437 y el tipo no es String437 y que la deje tal cual si el tipo si es String437, y en esta aplicación no funciona.:confused: |
incluso he probado esto
y tampoco, estoy confundido:confused: |
cesarsoftware,
Cita:
Cita:
Cita:
![]() Revisa este código relacionado a la imagen anterior: El código anterior utiliza el Codepage 437 definido a nivel de la aplicación por medio del tipo AnsiString, como se puede ver en la siguiente imagen: ![]() Te sugiero usar el CodePage 437 a nivel de la aplicación por medio del tipo AnsiString, el cual reflejara el CodePage definido a nivel de la aplicación, como se indica en las imágenes y en el código del ejemplo y permitirá enviar la información del Servidor al Cliente Remoto en función del formato requerido en el Msg #1. Nota: El CodePage a nivel de la aplicación solo aplica por medio del tipo AnsiString. Espero sea útil :) Nelson. |
Muchisimas gracias nelson,
Creo que cuando prove el codepage a nivel de aplicación, usaba el tipo string, pero lo pruebo ahora mismo y te cuento si funciona en la segunda aplicación, pero si es asi a partir ed ahora codepage 437 para todos los nuevos proyectos:D, porque .... El Ascii de toda la vida es el 437 ¿o estoy mu anticuado:o? |
| La franja horaria es GMT +2. Ahora son las 11:02:29. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi