|
replace:
theIterator = find(pSwitch);
with:
StringType sSwitch = StringType(_T("-")) + pSwitch;
theIterator = find(sSwitch);
|
|
|
|
|
why not just call GetArgumentCount with '-' as part of the switch?
|
|
|
|
|
It won't work, because find() works with StringType(=tstring), but input parameter is char*.
EDIT: '-' can't be part of input string, because GetArgumentCount uses HasSwitch fn, which appends this character to the input string.
|
|
|
|
|
xpk7 wrote: GetArgumentCount uses HasSwitch fn, which appends this character to the input string.
ah. that's right.
good catch.
|
|
|
|
|
I have an application that already uses some command line parameters with no switches, so it can be setup to run by default when I double-click a particular file type. I found that by adding a few lines to CCmdLine::SplitLine() I can support this:
CCmdLine::iterator theIterator;
theIterator = find(curParam);
if (theIterator!=end())
{
(*theIterator).second.m_strings.push_back(argv[i]);
}
else
{
CCmdParam cmd;
cmd.m_strings.push_back(argv[i]);
pair<CCmdLine::iterator, bool> res = insert(CCmdLine::value_type(curParam, cmd));
}
I can then use a blank switch to access this param:
wstringSrc = cmdLine.GetArgument(_T(""), 0);
if (cmdLine.GetArgumentCount(_T("")) > 1)
{
wstringDest = cmdLine.GetArgument(_T(""), 1);
}
|
|
|
|
|
Here is a little contribution: a small C++ class which only uses standard C and then compiles well. I have been using it for 15 years under Windows, Linux, etc, for console applications chiefly.
From comments in source code, its use is quite straightforward.
Under MS Visual Studio, however I advise to avoid using Unicode if not necessary and use Multi-Byte Character Set instead. This is generally enough for console utility applications.
Source code here:
args.hpp
args.cpp
|
|
|
|
|
This class is extremely handy. Thanks!
|
|
|
|
|
Hi Chris
I was just wondering what exception type gets thrown? Wouldn't you be better catching that type explicitly? Using catch (...) is not particularly good practice, especially in this context.
Mike
|
|
|
|
|
Mike Diack wrote:
I was just wondering what exception type gets thrown?
in the version that's currently posted, it's just an (int)0.
|
|
|
|
|
Hi, Chris
I read your code and found the class CCmdLine is derived from _CCmdLine of which type is a stl::map.
It causes something wrong because stl::map hasn't a virutal destructor. Please refer the chapter of <<effective c++="">>.
So I suggest using _CCmdLine as a member variable of CCmdLine rather than as a parent.
Jeff
|
|
|
|
|
Member 1216821 wrote: It causes something wrong
in this case, there is no problem. it would be a problem is CCmdLine had a non-trivial destructor. but, as it is written here, CCmdLine has no destructor, and no member variables, so it doesn't matter if its destructor is not called - there's nothing to destruct.
but, yes, this class was written long before i learned that one should not derive from an STL container. it just happens to work, regardless.
|
|
|
|
|
Hey i'm tring to add your files to my project but i can't get it to compile.
1>CmdLine.cpp(97): error C2664: 'void std::vector<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'char *' to 'CString &&'
1> with
1> [
1> _Ty=CString
1> ]
1> Reason: cannot convert from 'char *' to 'CString'
1> Constructor for class 'ATL::CStringT<BaseType,StringTraits>' is declared 'explicit'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1>CmdLine.cpp(162): error C2664: 'std::_Tree_iterator<_Mytree> std::_Tree<_Traits>::find(const ATL::CStringT<BaseType,StringTraits> &)' : cannot convert parameter 1 from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits> &'
1> with
1> [
1> _Mytree=std::_Tree_val<std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>>,
1> _Traits=std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>,
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> and
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Reason: cannot convert from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits>'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Constructor for class 'ATL::CStringT<BaseType,StringTraits>' is declared 'explicit'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1>CmdLine.cpp(229): error C2664: 'std::_Tree_iterator<_Mytree> std::_Tree<_Traits>::find(const ATL::CStringT<BaseType,StringTraits> &)' : cannot convert parameter 1 from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits> &'
1> with
1> [
1> _Mytree=std::_Tree_val<std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>>,
1> _Traits=std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>,
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> and
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Reason: cannot convert from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits>'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Constructor for class 'ATL::CStringT<BaseType,StringTraits>' is declared 'explicit'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1>CmdLine.cpp(232): warning C4018: '>' : signed/unsigned mismatch
1>CmdLine.cpp(241): error C2664: 'ATL::CStringT<BaseType,StringTraits>::CStringT(const VARIANT &)' : cannot convert parameter 1 from 'const char [1]' to 'const VARIANT &'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Reason: cannot convert from 'const char [1]' to 'const VARIANT'
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1>CmdLine.cpp(261): error C2664: 'std::_Tree_iterator<_Mytree> std::_Tree<_Traits>::find(const ATL::CStringT<BaseType,StringTraits> &)' : cannot convert parameter 1 from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits> &'
1> with
1> [
1> _Mytree=std::_Tree_val<std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>>,
1> _Traits=std::_Tmap_traits<CString,CCmdParam,std::less<CString>,std::allocator<std::pair<const CString,CCmdParam>>,false>,
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> and
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Reason: cannot convert from 'const char *' to 'const ATL::CStringT<BaseType,StringTraits>'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1> Constructor for class 'ATL::CStringT<BaseType,StringTraits>' is declared 'explicit'
1> with
1> [
1> BaseType=wchar_t,
1> StringTraits=StrTraitMFC_DLL<wchar_t>
1> ]
1>
1>Build FAILED.
|
|
|
|
|
which compiler?
what compiler settings?
MFC/no MFC?
ATL?
?
|
|
|
|
|
I met the same problem in a VC2010 MFC Unicode projct.
Could you help me to take a look at it?
Thanks in advance.
I just did:
1. Setup a mfc unicode dialog project in vc 2010
2. add CCmdLine.h and .cpp to the project
3. uncomment the #include"stdafx.h"
4. drag a button to the dialog and add "CCmdLine cmdLine;" in the handle function.
the these errors came to me...
modified on Thursday, August 25, 2011 1:45 AM
|
|
|
|
|
yes, this needs some slight modifications before it can be used in Unicode projects.
1. in CCmdLine::IsSwitch , you need to change strlen to _tcslen
2. in CmdLine.h and CmdLine.cpp, change all "char " to "TCHAR "
3. at the bottom of CCmdLine::GetArgument , change return "" to return CString("");
|
|
|
|
|
Thanks for the quick reply, and it works!
By the way, do you have any idea how it can parse a CString or TCHAR*, rather than argc & argv?
Could you give an implementation?
helfrich's implementation contains some errors while compiling.
|
|
|
|
|
to do that you would need some code to split the input string into substrings, using a space as a delimiter. then, pass your array of substrings to SplitString.
something like this...
#define MAX_TOKENS 100
TCHAR *tokens[MAX_TOKENS];
int curToken = 0;
CString cstr = _T("skip -f1 foo bar -f2 blah");
TCHAR * str = (LPCTSTR)cstr;
TCHAR * pch = _tcstok (str,_T(" "));
while (pch != NULL)
{
tokens[curToken++] = pch;
pch = _tcstok (NULL, _T(" "));
}
cmdLine.SplitString(curToken - 1, tokens);
(i haven't tried running that. might need some tweaking)
|
|
|
|
|
good to see that you're still around Chris - I was thinking of you the other night - anytime I needed to do Command Line args in VC6, CCmdLine was there for me .. now I do the occasional job in c#, and sure, there's lots of things out there, but nothing with quite the same 'feel'/'simplicity' .. I almost felt like writing my own CCmdLine in C# just so it carries on
so thanks for CCmdLine, I hope you and yours are doing well - dont see ya much around CP these days, unless you're hanging out in other forums
'g'
|
|
|
|
|
I'm using a console app - it seems that the main function is returning me the switch '-' in argv as the only character
My generated main function looks like this:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
The first thing I do is this:
CCmdLine Line;
Line.SplitLine(argc, (char**) argv);
However, in the implementation of SplitLine, IsSwitch always returns false (even though the first parameter passed to the command line is -z) (because argv[0] is '-' and IsSwitch return false when length == 1
Should I not be converting argv to (char**) as I'm doing (I do this because I get the following compile error if I don't:
error C2664: 'CCmdLine::SplitLine' : cannot convert parameter 2 from 'TCHAR *[]' to 'char **'
Thanks for your help!
Mike
|
|
|
|
|
are you building in Unicode ?
|
|
|
|
|
Nope - that's probably it huh? I guess it's because it creates a unicode project first - but when I switched it to a normal project, TCHAR should be changed to char - right?
|
|
|
|
|
Same problem if I change TCHAR to char... IsSwitch never returns true...
|
|
|
|
|
as a test i:
1. defined "UNICODE" in the build pre-proc settings
2. changed all char to TCHAR
3. changed strlen to _tcsclen
and it worked as expected for me. (VC6, console app)
|
|
|
|
|
Did the generate code for your main function look like this?
int _tmain(int argc, char* argv[], char* envp[])
|
|
|
|
|
no. just a plain old main(int, char**) .
update: (although, on converting the project to VS08, main now has the envp param).
|
|
|
|
|