Hva er forskjellen mellom _tmain () og main () i C ++?

stemmer
211

Hvis jeg kjører min C ++ program med følgende main () metoden alt er OK:

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;
}

Jeg får det jeg forventer og mine argumenter blir skrevet ut.

Men hvis jeg bruker _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;
}

Den viser bare den første bokstaven i hvert argument.

Hva er forskjellen forårsaker dette?

Publisert på 21/05/2009 klokken 23:45
kilden bruker
På andre språk...                            


5 svar

stemmer
10

den _T konvensjonen blir brukt til å indikere programmet skal bruke tegnsettet som for programmet (Unicode, ASCII, MBCS, etc.). Du kan omgi dine strenger med _T () for å ha dem lagret i riktig format.

 cout << _T( "There are " ) << argc << _T( " arguments:" ) << endl;
Svarte 21/05/2009 kl. 23:47
kilden bruker

stemmer
329

_tmainfinnes ikke i C ++. maingjør.

_tmain er en Microsoft forlengelse.

mainer, i henhold til C ++ standard, programmets inngangspunkt. Den har en av disse to signaturer:

int main();
int main(int argc, char* argv[]);

Microsoft har lagt til en wmain som erstatter andre signatur for denne:

int wmain(int argc, wchar_t* argv[]);

Og så, for å gjøre det enklere å bytte mellom Unicode (UTF-16) og deres multibyte tegnsett, har de definert _tmainsom, hvis Unicode er aktivert, er utarbeidet som wmain, og ellers main.

Som for den andre delen av spørsmålet ditt, den første delen av puslespillet er at hovedfunksjon er galt. wmainbør ta et wchar_targument, ikke char. Siden kompilatoren ikke håndheve dette for mainfunksjonen, får du et program der en rekke wchar_tstrenger sendes til mainfunksjonen, som tolker dem som charstrenger.

Nå, i UTF-16, tegnsett av Windows når Unicode er aktivert, blir alle ASCII-tegn representert som to byte \0etterfulgt av ASCII-verdien.

Og siden x86 CPU er lite endian, er rekkefølgen av disse bytes byttet, slik at ASCII-verdi kommer først, deretter etterfulgt av en null byte.

Og i en char streng, hvordan blir strengen vanligvis avsluttet? Jepp, med en null byte. Så programmet ser en haug med strenger, hver og en byte lang.

Vanligvis har du tre alternativer når du gjør Windows-programmering:

  • Eksplisitt bruke Unicode (ringe wmain, og for hver Windows API-funksjonen som tar røye relaterte argumenter, ring -Wversjon av funksjon. I stedet for Create, ring CreateWindowW). Og i stedet for å bruke charbruk wchar_t, og så videre
  • Eksplisitt deaktivere Unicode. Ring hoved, og CreateWindowA, og bruker charfor strenger.
  • Tillat begge. (Kaller _tmain, og Create, som vilje til hoved / _tmain og CreateWindowA / CreateWindowW), og bruk TCHAR stedet for røye / wchar_t.

Det samme gjelder for de strengtyper som er definert ved windows.h: LPCTSTR går over til enten LPCSTR eller LPCWSTR, og for enhver annen type som inneholder røye eller wchar_t, alltid finnes et -T- versjon som kan brukes i stedet.

Legg merke til at alt dette er Microsoft bestemt. TCHAR er ikke en standard C ++ typen, det er en makro definert i windows.h. wmain og _tmain er også definert av bare Microsoft.

Svarte 22/05/2009 kl. 00:09
kilden bruker

stemmer
34

_tmain er en makro som blir omdefinert avhengig av hvorvidt du kompilere med Unicode eller ASCII. Det er en Microsoft forlengelse og er ikke garantert å fungere på andre kompilatorer.

Det riktige erklæringen er

 int _tmain(int argc, _TCHAR *argv[]) 

Hvis makro UNICODE er definert, utvides den til

int wmain(int argc, wchar_t *argv[])

Ellers er det utvides til

int main(int argc, char *argv[])

Din definisjon går for litt av hvert, og (hvis du har UNICODE definert) vil utvide til

 int wmain(int argc, char *argv[])

som er rett og slett feil.

std :: cout arbeider med ASCII-tegn. Du trenger std :: wcout hvis du bruker store bokstaver.

prøve noe sånt som dette

#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;
}

Eller du kan bare bestemme på forhånd om du skal bruke brede eller smale tegn. :-)

Oppdatert 12 november 2013:

Endret den tradisjonelle "TCHAR" til "_TCHAR", som synes å være den siste mote. Både fungere fint.

End Update

Svarte 23/05/2009 kl. 08:39
kilden bruker

stemmer
5

Ok, synes spørsmålet å ha blitt besvart ganske godt, bør UNICODE overbelastning ta et bredt tegn array som sin andre parameter. Så hvis kommandolinjeparameteren er "Hello"som trolig ville ende opp som "H\0e\0l\0l\0o\0\0\0", og programmet vil bare skrive ut 'H'før den ser hva den mener er en null terminator.

Så nå kan du lurer på hvorfor det enda kompilerer og lenker.

Vel det kompilerer fordi du har lov til å definere en overbelastning i en funksjon.

Kobling er en litt mer komplisert problem. I C, er det ingen dekorert symbol informasjonen slik at den bare finner en funksjon kalt hoved. Den argc og argv er nok alltid det som call-stack parametere i tilfelle selv om funksjonen er definert med at signatur, selv om din funksjon som skjer å ignorere dem.

Selv om C ++ har dekorert symboler, det nesten helt sikkert bruker C-kobling for main, snarere enn en smart linker som ser ut for dem etter tur. Så det har funnet din wmain og sette parametrene på call-stabelen i tilfelle det er den int wmain(int, wchar_t*[])versjonen.

Svarte 15/10/2012 kl. 09:30
kilden bruker

stemmer
0

Med litt innsats av templatizing dette, det wold arbeide med noen liste over objekter.

#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';
}
Svarte 02/07/2017 kl. 09:45
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more