C++ - arguments to main

大兔子大兔子 提交于 2019-12-24 21:59:59

问题


very basic question. i try to write a program that outputs the filenames of the files dragged onto the exe.

i followed this guide for main arguments: http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html

this is my code:

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    cout<<"num arguments: "<<argc<<"\n";

    while(argc--)
        printf("%s\n", *argv++);

    cout<<"press any key";
    getchar();
    return 0;
}

but all it output's is:

if i run it without dragging&dropping files onto the exe:

num arguments: 1

G

press any key

if i drag&drop 3 files it will output:

num arguments: 4

G

G

G

G

press any key

neither the application name, nor the name of any of the files starts with "G"

what's the problem?

thanks!


回答1:


You're only getting the first letter because you're mixing Unicode and not. I can't explain the Gs sorry (unless all your files are on drive G:?) but you'll see the full filenames with

while(argc--)
    _tprintf(_T("%s\n"), *argv++);

instead.

Afterthought, and beaten to it by sbi's answer: I can't find a _tcout to use as

_tcout << *argv++;

instead if you wanted to stay C++ - I guess you'd have to define one, e.g.

#ifdef _UNICODE
#define _tcin wcin
#define _tcout wcout
#define _tcerr wcerr
#define _tclog wclog
#else
#define _tcin cin
#define _tcout cout
#define _tcerr cerr
#define _tclog clog
#endif

although this being C++ they probably shouldn't be defines but something else, and I'm not 100% sure what.




回答2:


argv[0] is always the executable's name. (Which means that argc > 0 is always true.) If you want to output wide characters (I think _TCHAR maps to wchar_t, BICBWT), you must not use narrow output. In C++, outputting is done using output streams. The wide console output stream is std::wcout.

#include <iostream>

//Beware, brain-compiled code ahead!
template< typename InpIt >
void output(InpIt begin, InpIt end)
{
  while(begin != end)
    std::wcout << *begin++ << L'\n';
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::wcout << L"num arguments: " << std::argc << L'\n';

    output(argv+1, argv+argc)

    return 0;
}

As Rup mentions, _TCHAR changes its value (char or wchar_t) depending on some definition.

First and foremost: Do you really need this switching? In practice, when you need wide characters, then most often you really need them and the program won't work correctly with narrow characters.
So it's very likely you can just settle to pure wide characters, get rid of the switching, and use the above code as written.

However, if you really need to switch, you need to switch between narrow and wide console streams yourself. (This is only true for the console stream objects, BTW. For your own streams, say, for example, file streams, you can just use _TCHAR and let the compiler figure out the rest: std::basic_ofstream<_TCHAR>.) One way to do this would be a traits class:

//Beware, brain-compiled code ahead!
template< typename Char >
struct console_stream_traits; // leave undefined

template<>
struct console_stream_traits<char> {
  typedef std::basic_ostream<char> ostream;
  typedef std::basic_istream<char> istream;
  std::basic_ostream<char>& cout = std::cout;
  std::basic_ostream<char>& cerr = std::cerr;
  std::basic_ostream<char>& clog = std::clog;
  std::basic_istream<char>& cin  = std::cin;
};

template<>
struct console_stream_traits<wchar_t> {
  typedef std::basic_ostream<wchar_>  ostream;
  typedef std::basic_istream<wchar_>  istream;
  std::basic_ostream<wchar_t>& cout = std::wcout;
  std::basic_ostream<wchar_t>& cerr = std::wcerr;
  std::basic_ostream<wchar_t>& clog = std::wclog;
  std::basic_istream<wchar_t>& cin  = std::wcin;
};

typedef console_stream_traits<_TCHAR> my_ostream;
typedef my_console_stream_traits::ostream    my_ostream;
typedef my_console_stream_traits::ostream    my_ostream;

my_ostream& my_cout = my_console_stream_traits::cout;
my_ostream& my_cerr = my_console_stream_traits::cerr;
my_ostream& my_clog = my_console_stream_traits::clog;
my_istream& my_cin  = my_console_stream_traits::cin;

With that, the loop in the output() function above would become:

while(begin != end)
  my_cout << *begin++ << _T('\n');



回答3:


Just use ASCII 'main' function and everything will be OK. Change

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

to

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



回答4:


Use this:

while(argc--)
    printf("%s\n", argv[argc]);


来源:https://stackoverflow.com/questions/3171461/c-arguments-to-main

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!