问题
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