programa - ¿Cuál es la diferencia entre_tmain() y main() en C++?
metodo main c (5)
Con un poco de esfuerzo para templar esto, funcionará con cualquier lista de objetos.
#include <iostream>
#include <string>
#include <vector>
char non_repeating_char(std::string str){
while(str.size() >= 2){
std::vector<size_t> rmlist;
for(size_t i = 1; i < str.size(); i++){
if(str[0] == str[i]) {
rmlist.push_back(i);
}
}
if(rmlist.size()){
size_t s = 0; // Need for terator position adjustment
str.erase(str.begin() + 0);
++s;
for (size_t j : rmlist){
str.erase(str.begin() + (j-s));
++s;
}
continue;
}
return str[0];
}
if(str.size() == 1) return str[0];
else return -1;
}
int main(int argc, char ** args)
{
std::string test = "FabaccdbefafFG";
test = args[1];
char non_repeating = non_repeating_char(test);
Std::cout << non_repeating << ''/n'';
}
Si ejecuto mi aplicación C ++ con el siguiente método main (), todo está bien:
int main(int argc, char *argv[])
{
cout << "There are " << argc << " arguments:" << endl;
// Loop through each argument and print its number and value
for (int i=0; i<argc; i++)
cout << i << " " << argv[i] << endl;
return 0;
}
Obtengo lo que espero y mis argumentos se imprimen.
Sin embargo, si uso _tmain:
int _tmain(int argc, char *argv[])
{
cout << "There are " << argc << " arguments:" << endl;
// Loop through each argument and print its number and value
for (int i=0; i<argc; i++)
cout << i << " " << argv[i] << endl;
return 0;
}
Simplemente muestra el primer carácter de cada argumento.
¿Cuál es la diferencia que causa esto?
La convención _T se utiliza para indicar que el programa debe usar el conjunto de caracteres definido para la aplicación (Unicode, ASCII, MBCS, etc.). Puede rodear sus cadenas con _T () para guardarlas en el formato correcto.
cout << _T( "There are " ) << argc << _T( " arguments:" ) << endl;
Ok, la pregunta parece haber sido respondida bastante bien, la sobrecarga de UNICODE debería tomar una matriz de caracteres amplia como su segundo parámetro. Entonces, si el parámetro de la línea de comando es "Hello"
, probablemente terminará como "H/0e/0l/0l/0o/0/0/0"
y su programa solo imprimirá la ''H''
antes de que vea lo que cree que es un terminador nulo.
Así que ahora usted puede preguntarse por qué incluso compila y enlaces.
Bueno, se compila porque se le permite definir una sobrecarga a una función.
La vinculación es un tema un poco más complejo. En C, no hay información de símbolos decorados, por lo que solo encuentra una función llamada main. El argc y el argv probablemente estén siempre ahí como parámetros de la pila de llamadas, por si acaso, incluso si su función está definida con esa firma, incluso si su función pasa a ignorarlos.
A pesar de que C ++ tiene símbolos decorados, es casi seguro que utiliza el enlace C para el enlace principal, en lugar de un inteligente que busca cada uno por su parte. Así que encontró su wmain y puso los parámetros en la pila de llamadas en caso de que sea la int wmain(int, wchar_t*[])
.
_tmain es una macro que se redefine dependiendo de si compila con Unicode o ASCII. Es una extensión de Microsoft y no se garantiza que funcione en ningún otro compilador.
La declaración correcta es
int _tmain(int argc, _TCHAR *argv[])
Si la macro UNICODE está definida, eso se expande a
int wmain(int argc, wchar_t *argv[])
De lo contrario se expande a
int main(int argc, char *argv[])
Su definición va para un poco de cada uno, y (si tiene un UNICODE definido) se expandirá a
int wmain(int argc, char *argv[])
que es simplemente un error.
std :: cout funciona con caracteres ASCII. Necesitas std :: wcout si estás usando caracteres anchos.
prueba algo como esto
#include <iostream>
#include <tchar.h>
#if defined(UNICODE)
#define _tcout std::wcout
#else
#define _tcout std::cout
#endif
int _tmain(int argc, _TCHAR *argv[])
{
_tcout << _T("There are ") << argc << _T(" arguments:") << std::endl;
// Loop through each argument and print its number and value
for (int i=0; i<argc; i++)
_tcout << i << _T(" ") << argv[i] << std::endl;
return 0;
}
O simplemente puedes decidir por adelantado si usar caracteres anchos o estrechos. :-)
Actualizado el 12 de noviembre de 2013:
Se cambió el tradicional "TCHAR" a "_TCHAR", que parece ser la última moda. Ambos funcionan bien.
Actualización final
_tmain
no existe en C ++. main
hace
_tmain
es una extensión de Microsoft.
main
es, según el estándar C ++, el punto de entrada del programa. Tiene una de estas dos firmas:
int main();
int main(int argc, char* argv[]);
Microsoft ha agregado un wmain que reemplaza la segunda firma con esto:
int wmain(int argc, wchar_t* argv[]);
Y luego, para facilitar el cambio entre Unicode (UTF-16) y su conjunto de caracteres multibyte, han definido _tmain
que, si Unicode está habilitado, se compila como wmain
y, por lo demás, como main
.
En cuanto a la segunda parte de su pregunta, la primera parte del rompecabezas es que su función principal es incorrecta. wmain
debería tomar un argumento wchar_t
, no char
. Como el compilador no impone esto para la función main
, obtienes un programa donde se pasa una serie de cadenas wchar_t
a la función main
, que las interpreta como cadenas de caracteres.
Ahora, en UTF-16, el conjunto de caracteres utilizado por Windows cuando está habilitado Unicode, todos los caracteres ASCII se representan como el par de bytes /0
seguido del valor ASCII.
Y dado que la CPU x86 es little-endian, el orden de estos bytes se intercambia, de modo que el valor ASCII aparece primero y luego un byte nulo.
Y en una cadena de caracteres, ¿cómo se termina usualmente la cadena? Sí, por un byte nulo. Así que su programa ve un montón de cadenas, cada byte de largo.
En general, tienes tres opciones al hacer la programación de Windows:
- Utilice explícitamente Unicode (llame a wmain, y para cada función de la API de Windows que tome argumentos relacionados con el carácter de caracteres, llame a la versión
-W
de la función. En lugar de CreateWindow, llame a CreateWindowW). Y en lugar de usarchar
usewchar_t
, y así sucesivamente - Deshabilita explícitamente Unicode. Llame a main y CreateWindowA, y use
char
para cadenas. - Permitir ambos. (llame a _tmain y CreateWindow, que se resuelven a main / _tmain y CreateWindowA / CreateWindowW), y use TCHAR en lugar de char / wchar_t.
Lo mismo se aplica a los tipos de cadena definidos por windows.h: LPCTSTR se resuelve en LPCSTR o LPCWSTR, y para cualquier otro tipo que incluya char o wchar_t, siempre existe una versión -T- que puede usarse en su lugar.
Tenga en cuenta que todo esto es específico de Microsoft. TCHAR no es un tipo estándar de C ++, es una macro definida en windows.h. wmain y _tmain también están definidos solo por Microsoft.