2009-10-10 14 views
14

Tengo una matriz TCHAR en mi código C++ a la que quiero asignar cadenas estáticas.Cómo asignar un valor a una matriz TCHAR

puse una cadena inicial a ella a través

TCHAR myVariable[260] = TEXT("initial value"); 

Todo funciona bien en esto. Sin embargo, cuando me separé en dos líneas como en

TCHAR myVariable[260]; 
myVariable = TEXT("initial value"); 

TI errores y da un error del compilador:

error C2440: '=': cannot convert from 'const char [14]' to 'TCHAR [260]'

debe no la función TEXT() hacer exactamente lo que quiere aquí? convertir la cadena dada a TCHAR s? ¿Por qué funciona, al juntar las dos líneas? ¿Qué tengo que cambiar para que funcione?

Algunos otra cosa confusa que he encontrado:

He buscado en internet para ello y han visto que hay también _T() y _TEXT() y __T() y __TEXT(). ¿Para qué son? ¿Cuál de ellos debería usar en qué entorno?

Respuesta

19

El motivo por el que la asignación no funciona tiene muy poco que ver con TCHAR sy _T. Lo siguiente tampoco funcionará.

char var[260]; 
var = "str"; // fails 

La razón es que en C y C++ no puede asignar matrices directamente. En su lugar, debe copiar los elementos uno por uno (usando, por ejemplo, strcpy, o en su caso _tcscpy).

strcpy(var, "str"); 

En cuanto a la segunda parte de su pregunta, TEXT, _T y los otros son macros, que se basa en Unicode convertir una cadena literal a una amplia cadena literal. En las compilaciones que no sean Unicode, no hacen nada.

+1

+1 a avakar. En una nota lateral, use TCHAR en lugar de WCHAR o char, dependiendo de la configuración de su proyecto (Unicode/ASCII), la macro TCHAR se definirá como WCHAR/char. Asimismo, utilice funciones seguras basadas en t como _tcscpy_s, _tcscat_s, etc. que se definirán de nuevo en función de su proyecto. ajustes como wcscpy o strcpy. Mis 2 centavos. – legends2k

+0

Intenté esto, obtuve este error: error C2664: 'wcscpy': no ​​se puede convertir el parámetro 2 de 'const char [8]' a 'const wchar_t *' –

+0

@ user396483, ¿qué intentó? Obviamente estás mezclando las versiones str, _tcs y wcs. – avakar

5

See avakar's answer for the direct answer. I was going to add this as a comment, but it really is a freestanding recommendation. I will warn you up from that this will sound like a rant but it does come from using TCHAR and then working issues for a few years before trying to remove it from a rather large codebase.

Asegúrese de que usted realmente entiende el efecto de usar TCHAR matrices y sus amigos. Son engañosamente difíciles de usar correctamente. He aquí una breve lista de cosas que hay que tener en cuenta:

  • sizeof(TCHAR) es condicional: Examinar código que contiene este. Si está haciendo algo diferente al cálculo del tamaño que se está pasando a malloc() o memcpy(), entonces probablemente sea incorrecto.
  • TCHAR es un alias de tipo: Desde TCHAR es nada más que un typedef, es muy fácil escribir cosas como wcscpy(tszStr, wszAry) y sin enterarse. Básicamente, TCHAR es ya seachar o wchar_t, por lo que las selecciones de sobrecarga pueden sorprenderlo.
  • wsprintf() y swprintf() son diferentes: Este es un caso especial de los anteriores, pero tiene una consideración especial ya que es muy fácil cometer un error aquí.

Si desea utilizar TCHAR, a continuación, asegúrese de que se compila tanto Unicode y MBCS versiones con regularidad. Si no haces esto, entonces probablemente vayas a deshacer cualquier ventaja que estés tratando de ganar usándolos en primer lugar.

Aquí hay dos recomendaciones que tengo para cómo no usar TCHAR en primer lugar cuando está escribiendo código C++.

  1. Use CString si está utilizando MFC o si se siente cómodo si se une a MSFT.
  2. Utilice std::string o std::wstring junto con la API específica del tipo - use CreateFileA() y CreateFileW() según corresponda.

Personalmente, elijo esto último pero la codificación de caracteres y los problemas de transcodificación de cadenas son solo una pesadilla de vez en cuando.

+0

+1, originalmente consideré escribir una diatriba similar. Personalmente, siempre uso 'std :: string' con datos codificados en utf-8, recodificando solo en los límites de la API (es decir, antes de las llamadas a la API de win32). – avakar

+0

@avakar: hemos hecho tanto el enfoque UTF-8 + std :: string como UCS-2 + std :: wstring. Llegué al último caso desde el plegado de casos y las comparaciones son mucho más fáciles en Unicode que en UTF-8. –

Cuestiones relacionadas