If so how? Because currently trying to handle input for multiple players using a map of actions.
std::vector<std::map<a,b> >
or if you want to handle the construction/destruction yourself
std::vector<std::map<a,b>* >
where a and b are the keys/values in your map
For example:
#include <vector>
#include <map>
int main(int argc, char* argv[])
{
std::vector<std::map<int,int>> vecOfMaps;
std::vector<std::map<int,int>*> vecOfMaps2;
return 0;
}
Related
I want to have a dynamic structure which I could iterate on, there will be unknown number of entries and known number of strings for each entry. I thought that vector of array of strings could be the way, however I get error while compiling this:
vector< array<string, 5> >
error: invalid use of incomplete type 'struct std::array<std::basic_string<char>, 5u>'
What am I doing wrong? and if this is kind of the way - how would I add/get values to/from this structure?
Did you include all these three headers?
#include <vector>
#include <array>
#include <string>
This compiles just fine:
#include <vector>
#include <array>
#include <string>
int main(int argc, char const *argv[])
{
std::vector<std::array<std::string, 5> > myVec;
return 0;
}
This is the first time I use AddObject method in C++ Builder 6 in a TStringList
but I can not add an integer to the object list for example. Of course I did it by means of casting different types. But it's not what I want. Please help me do it simpler
and why the objects must be Tobject* in object list
this is my simple program...
#include <vcl.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
int main(int argc, char* argv[])
{
int r=random(100+1);
TStringList *mylist=new TStringList;
mylist->AddObject("r",(TObject *)r);
int i=mylist->IndexOf("r");
int a=(int)(mylist->Objects[i]);
cout<<a<<endl;
getch();
return 0;
}
Use a std::map or other suitable container instead, eg:
#pragma hdrstop
#include <iostream.h>
#include <conio.h>
#include <map>
#pragma argsused
int main(int argc, char* argv[])
{
int r = random(100+1);
std::map<std::string, int> mylist;
mylist["r"] = r;
int a = mylist["r"];
cout << a << std::endl;
getch();
return 0;
}
why the objects must be Tobject*
Because of Borland's design of VCL.
mylist->AddObject("r",(TObject *)r);
Do not do this, because there's no guarantee that TStringList wouldn't call some methods of TObject* inside AddObject. For example it can call objectName() or incrementReference() (I know, that there's no TStringList::incrementReference() but it's just an example).
IMHO, all that you need is std::map:
#include <map>
int main()
{
int r=random(100+1);
std::map< AnsiString, int > myList;
myList[ "r" ] = r;
int a = myList[ "r" ];
}
It's very ugly but the cast will work fine. The pragmatic approach is to stick with that method if you must use TStringList.
If you wanted, you could add TObject derived wrappers that hold 'int's to another vector and use these pointers but it require more code to maintain that second list, is more prone to errors and a lot slower.
Alternatively new these wrappers and add them to the stringlist and then manage deletion of the objects manually. This is error prone.
The best approach may be to ditch TStringList if that is possible. Use a struct/class or a std::pair and std::vector or std::deque.
e.g.
typedef std::pair<AnsiString, int> MyValue;
typedef std::vector<MyValue> MyValueList;
MyValueList list;
list.push_back(MyValue("hello", 1));
AnsiString const& s = list[0].first;
int i = list[0].second;
im coming from PHP where i would do
$um['Im a string'][1] = 3;
for a 2d associative array where the first key is a string, the second an integer and the value is an integer as well. I try to do the same in c++. here is my attempt:
// experiment.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <unordered_map>
#include <vector>
#include <string>
using std::vector;
using std::string;
using std::unordered_map;
int _tmain(int argc, _TCHAR* argv[])
{
unordered_map <string,vector<int,int>> um;
um["Im a string"][1] = 3;
printf("Out: %d", um["Im a string"][1]);
return 0;
}
obviously its not the right syntax;
vector<int,int> isn't correct (vector isn't an associative container), you probably want a nested unordered_map<int>. So:
unordered_map <string,unordered_map<int,int>> um;
i am new to using c++
When I execute the following code
i am aware it shouldn't draw anything at the moment i am just trying to change from using an array for vertex position to using a vector as i want to be able to calculate points then use a push_back to append them.
This minimal example won't compile:
#include <vector>
std::vector<float> vertexPositions;
const float triangle = 0.75f;
vertexPositions.push_back(triangle);
int main(int argc, char** argv)
{
return 0;
}
I get:
error: ‘vertexPositions’ does not name a type
vertexPositions.push_back(triangle); is a statement. It must be placed inside a function definition. It can not be placed in the global scope like that.
Move that line into for example main, and you should be fine.
Did you add #include <vector>?
I see your problem - the following line must appear in your main function :
vertexPositions.push_back(triangle);
I created a console application as an example:
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <vector>
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<float> vertexPositions;
const float triangle = 0.75f;
vertexPositions.push_back(triangle);
return 0;
}
Is there something simple you might be missing?
Is there a way to get c++ strings from the commandline like in Java?
public static void main(String[] args)
where args is an array of C++ strings?
Not precisely but you can come close easily.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef vector<string> CommandLineStringArgs;
int main(int argc, char *argv[])
{
CommandLineStringArgs cmdlineStringArgs(&argv[0], &argv[0 + argc]);
for (int i = 0; i < cmdlineStringArgs.size(); ++i)
{
cout << cmdlineStringArgs[i] << endl;
}
return 0;
}
This just uses the overloaded constructor for std::vector that takes a begining/ending iterator pair to copy the command line arguments into the vectors. It is much the same as java from there on.
You can likewise build and object around that vector with utility methods to convert arguments but there is almost no point. Also there are plenty of packages with object that deal with interpreting command line switches and such. ACE, POCO, QT, etc.. all come with such facilities.
You can use a vector to get the char array into strings.
#include <vector>
#include <string>
using namespace std;
int main (int argc, char** argv)
{
vector <string> args (argv, argv + argc);
}
Yes the main function can take 2 arguments
int main(int argc, char* argv[])
Where argc is the number of arguments and argv contains a list of the arguments.
For example if you run your program as:
MyProgram.exe hello
Then
argc = 2
argv[0] = MyProgram.exe
argv[1] = "hello"
Not built in to the language, but its very easy to implement:
#include <vector>
#include <string>
using namespace std;
int main( int argc, char *argv[] ) {
vector <string> args;
for ( int i = 0; i < argc; i++ ) {
args.push_back( argv[i] );
}
// do something with args
}
In C, your main function signature looks like this:
int main(int argc, char** argv).
argc contains the number of arguments passed in by the command line. The name of the executable is in position 0, and adds one to argc.
argv contains an array of strings containing the arguments. Again, position 0 is the name of the executable.
The standard C++ main() signature is
int main(int argc, char* argv[])
where argc denotes the count of commandline arguments and argv[] is an array of primitive C strings holding the commandline arguments. argv[0] is the executable, as invoked from the commandline.
If you are writing a win32 application, you can use GetCommandLineW http://msdn.microsoft.com/en-us/library/ms683156(VS.85).aspx and CommandLineToArgW http://msdn.microsoft.com/en-us/library/bb776391(VS.85).aspx
There is a comment on the CommandLineToArg page about special handling that is needed if your executable has spaces in the path and there are no arguments that you might have to handle.