How to convert string to long int in omnet++? - omnet++

In omnet++ 5.5.1, i declared a vector in NED file using string:
string state = default("1 2 3 4 5");
In the .cc file, I wrote
std::vector<std::string> statesStr = cStringTokenizer(par("state")).asVector();
std::vector<long> statesPar;
for (auto k : statesStr) {
// How to convert the string to long?
statesPar.push_back(k.c_str()); // error
}
The above code shows the below error
invalid conversion from ‘const char*’ to ‘std::vector::value_type {aka long int}’ [-fpermissive]
Would anyone please suggest to me how to fix the error? Thank you.

This is a basic C++ question, unrelated to OMNeT++. You cannot put a string into a long vector. Strings can be converted to long with the std::stol() function.

Related

How to solve the error "const inet::MacHeaderBase’ as ‘this’ argument discards qualifiers [-fpermissive]"

I am using the following header structure:
class MacHeaderBase extends FieldsChunk
{
MacAddress srcAdd;
MacAddress destAdd;
MacTypes type;
int morebit;
}
To set the morebit, I wrote hdr->setMorebit(1) as follows:
auto packet = currentTxFrame->dup();
const auto& hdr = packet->peekAtFront<MacHeaderBase>();
DestAddr = hdr->getDestAddr();
hdr->setMorebit(1);
However, I am getting error:
passing ‘const inet::MacHeaderBase’ as ‘this’ argument discards qualifiers [-fpermissive]
hdr->setMorebit(1);
Can anyone suggest how to resolve this error?
Method peetAtFront() returns an immutable chunk so one cannot change it. Use makeExclusivelyOwnedMutableChunk to convert it to a mutable chunk this way:
auto packet = currentTxFrame->dup();
auto& hdr = makeExclusivelyOwnedMutableChunk(packet->peekAtFront<MacHeaderBase>());
DestAddr = hdr->getDestAddr();
hdr->setMorebit(1);
EDIT
peekAtFront() should be used when one want to read a chunk and its fields. The recommended way to modify a chunk of a packet is:
use removeAtFront() to obtain a chunk and remove it from a packet
modify that chunk
insert that chunk to a packet using insertAtFront()

C++ templates reading type from configuration file at runtime

I've been trying to write a piece of code that reads a configuration file at runtime, and this file contains the names of different variables, and their type. These types are almost all builtin (int, unsigned int, char*, unsigned long long, float), with the exception of one class which stores information as binary flags.
Example configuration file contains:
Name std::string Measurement
PositionX float 0.004
PositionY float 0.002
Time unsigned long long 1521479000
Function which needs this information:
std::vector<float> xPos;
...
while( loops_over_a_file_containing_values );
...
xPos.push_back(get_information["PositionX"].extract<float>());
However, I cannot for the life of me seem to find a method in which to define these in a C++ code, most of my googling leads me to "This doesn't work" or answers that are so complicated to me that I cannot implement it in a reasonable way.
The main reason behind this is because there are a rather large number of variables with different types, and their type is needed as this function comes from another user written C++ package (which I have no way to modify in any shape or form).
So far I've looked at boost::any, boost::variant but I can't see how this could be done with those. And I'm unsure how exactly to go about this with templates either, I've tried:
template <int ModeDecider> class TypeDecider{ };
template <> class TypeDecider<0>{ public: typedef int Type; };
template <> class TypeDecider<1>{ public: typedef unsigned int Type; };
template <> class TypeDecider<2>{ public: typedef unsigned long long Type; };
template <> class TypeDecider<3>{ public: typedef float Type; };
...
std::string test1 = "unsigned long long";
std::string test2 = "1521479000";
switch( test1 ){
...
std::vector<TypeDecider<2>::Type> testvec;
testvec.push_back(static_cast<TypeDecider<2>::Type>(test2));
...}
But this gives me:
cannot convert 'std::__cxx11::string' (aka 'basic_string<char>') to 'TypeDecider<2>::Type' (aka 'unsigned long long') without a conversion operator
Which I'm not exactly sure how to go about fixing. And so far my googling-fu has yielded very little. As such, I'm here asking for help before I go to the awful step of writing a Python script in order to write the C++ script.

string length: invalid static_cast

I was expecting this sample code to work:
std::string s;
int number=1;
s = std::to_string(number);
int size=static_cast<int>(s.length);
However it gives the error:
main.cpp:178:39: error: invalid static_cast from type ‘’ to type ‘int’
int size=static_cast(s.length);
Then, I also tried:
int size=atoi(s.length);
Which gives me the error:
cannot convert ‘std::basic_string<_CharT, _Traits, _Alloc>::length<char, std::char_traits<char>
... to type ‘const char*’
Then, I tried this option:
int size=atoi(s.c_str());
This one worked. Any hints why atoi(s.length) does not work, and instead atoi(s.c_str()) is required?
So, suppose that I have the input string as 999, the total of digits will be 3. Using s.length would be the best way to get the total of digits, however the s.length casting gives the error.
You did not invoke the length method.
You should use int size=static_cast<int>(s.length());: notice the call operator at the end of the length method name.
However, if by doing this, you are trying to convert the string to an integer, this is wrong. This only gives you the number of characters in the string.

passing argument 1 of 'strlen' makes pointer from integer without a cast

It is not clear why I get a warning of:
[Warning] passing argument 1 of 'strlen' makes pointer from integer without a cast [enabled by default]
expected 'const char *' but argument is of type 'char'
on two of the 3 statements containing strlen() below.
Even when I attempted to cast *str it still gave the same warning.
bfr is a character buffer. *str points to that char buffer after the call to
gets(). If I use strlen(*str) I get a warning. If I use strlen(bfr) I do not.
But *str should be the equivalent to bfr. Thus the confusion regarding the error.
Now in reality, strlen arg 1 is defined as strlen(const char *string). So I
would have expected strlen(bfr) to also produce an error since bfr[] is a
char string and not a const char either.
And where is the integer that is being made into a pointer?
I am using gcc under wXDev-C++.
void test(){
FILE *fileID = fopen("somefile.txt","r");
char *str, len;
char bfr[16];
str = fgets(bfr,16,fileID); // str will be set equal to &bfr[0]
len = strlen(*str); // This gives a warning
len = strlen((const char)*str); // This gives a warning
len = strlen(bfr); // This does not give a warning
}
Sometimes you just need to take a fresh look in the morning at a problem. I realized that strlen is looking for a pointer to a string and 'str' is defined as a pointer. So *str would be a pointer to a pointer. So the warning was correct. It should read len = strlen(s) not len = strlen(*s). And it is 'str' pointing to 'bfr' not *str;
Answered my own question.

How to cast int to float in GLSL (WebGL)?

My code is (inside the void main):
float res;
for(int i=0; i<15; i++) {
res = float(i)/15.0;
//...
}
Unfortunately I get a syntax error at float(i)/15.0
If I just write i/15.0, then the error is:
wrong operand types no operation '/' exists that takes a left-hand operand of type 'mediump int' and a right operand of type 'const float' (or there is no acceptable conversion)
If I just try i/15 then the result is an integer, but I would like to get a float.
How is it possible to cast int to float?
It seems that you're not allowed to cast in GLSL. Therefore, "you have to use a constructor".
Try this:
// http://www.shaderific.com/glsl-types/
// "Implicit type conversions are not supported.
// Type conversions can be done using constructors..."
float i_float = float(i);
res = i_float / 15.0;
PS: If you have a look at the documentation, it says that "... Either integer type can be converted into floats, and integers and floats can be converted into doubles." ... I find it odd that your code is not accepted by the GLSL compiler. (cf. Reto Koradi's comment)

Resources