How to fetch the string using the substr with garbage characters? - c++

I have this string, if
size_t pos;
pos = eNBSWVerTmp.find("MAC");
When I print out the pos, pos 4294967295.
Is there a way I can fetch the string start from 1103?
♦ƒ+Hm.0_MAC_1103_064_00, 21.06.1ÿs7÷l ↕
I think garbage chars caused the pos out of range. Thanks in advance.

Do this:
std::string test("MAC");
std::copy(test.begin(), test.end(), std::ostream_iterator<int>(std::cout," "));
std::cout << "\n";
std::copy(eNBSWVerTmp.begin(), eNBSWVerTmp.end(), std::ostream_iterator<int>(std::cout," "));
std::cout << "\n";
Now see if the numbers in the top line match a similar sequence of numbers in the bottom line.
I am betting you will not find a match. But you may be able to work out why.

If you start by
const size_t pos = eNBSWVerTmp.find("MAC");
you know that pos indicates where M in MAC can be found (or is std::string::npos if not found).
To get some substring starting, say, 4 bytes forward from pos, you can do
std::string substring;
if (pos != std::string::npos)
substring = eNBSWVerTmp.substr(pos + 4, number_of_bytes);
to get the number_of_bytes you want.

The position 4294967295 isn't a garbage number, it's consistent with what happens if you store a negative number in an unsigned type such as size_t. This would be returned by find if the substring MAC can't be found. So it probably means there's an invisible character inside the substring MAC. You might try iterating through the string in an encoding-specific way, and appending characters to a new string (or std::vector<char>) only if they're expected characters (i.e. letters, digits, etc.), then finding MAC within that.

Related

How std::find_last_of actually works?

string s = "I Like C++ Tutorial";
cout << s.find_last_of("Like");
I know that find_last_of returns the last character that matches, however, it returns 16, which is the position of the letter i in Tutorial, But I'm confused because I'm searching for the last position of Like not i, I tried to remove i from the string. It returns 5 as I expected. But the question is why did it return 16?
find_last_of finds the last character equal to one of characters in the given character sequence.
The character sequence is "Like". The last L is at position 3, the last i is at position 16, the last k is at position 4 and the the last e is at position 5. So it returned the 16, the greatest of these values.
If the character sequence was "like" instead of "Like", it would have returned 18 because the last l is at position 18.
In case no letter in the character sequence that matches any letter in the string, npos is returned.
std::find_last_of
Finds the last character equal to one of characters in str
this means when searching the string "I Like C++ Tutorial" for the string "Like" the last character that apears in both strings is "i" wich is at position 16.
when searching for a complete string use std::find
std::string s("I Like C++ Tutorial");
std::cout << s.find("Like"); // prints 2
if you want to find the last occurence of the string use std::rfind
std::string s("I Like C++ Tutorial Like");
std::cout << s.rfind("Like"); // prints 20
to get the position of the last character in the last match you just have to add the length of the string:
std::string s("I Like C++ Tutorial Like");
std::string s2("Like");
std::cout << s.rfind(s2) + s2.length(); // prints 24

Initial Check to see if a Substring is within range

I am in the beginnings of learning C++ and I am wondering if there is a way to assert that a substring can be created from a String, given a range. My String will vary in size each iteration. I am trying to create six substrings from that original String. With this variation in size, I am sometimes trying to access indexes of the String that do not exist for that particular iteration.
For example, if my String in iteration 1 is 11 characters
My first substring is from 3 characters - valid
My second substring is the next 3 characters - valid
My third substring is the next 5 characters - valid
My fourth substring is the next 4 characters - not valid - crashes program
My fifth substring - not valid, out of range
My sixth substring - not valid, out of range
I am wondering if there is a small check I can do to assert the length is valid. It's worth noting, I suppose, that I have not set any default values to these substrings. They are declared as:
string subS1
string subS2
string subS3
...
...
string subS6
Would setting all 6 substrings to null upon declaration alleviate this issue and for any valid substring, the value will just be overwritten?
Thanks in advance
subS1 = str.substr(0, 3); // Could be valid range
subS2 = str.substr(3, 3); // Could be valid range
subS3 = str.substr(6, 5); // Could be valid range
subS4 = str.substr(11, 4); // Could be valid range
subS5 = str.substr(15, 4); // Could be valid range
subS6 = str.substr(19); // from the nineteenth character to the end
Algorithm--->
step 1: Get the length of string in current iteration in variable size.
step 2: Write this code in itertaion.
int i=0;
i= str.substr(start,end).length();
if( i>size) then,
std::cout<<"index exceeded";
Either check the size of str before extracting the string, or rely on std::string::substr's len parameter:
Number of characters to include in the substring (if the string is
shorter, as many characters as possible are used). A value of
string::npos indicates all characters until the end of the string.
Example:
#include <iostream>
#include <string>
int main ()
{
std::string str="Alexander the Great";
std::string str2 = str.substr (16, 25);
std::cout << str2 << '\n'; // eat
return 0;
}
It won't crash, it will just use as many characters as possible.
This however:
std::string str2 = str.substr (20, 25);
should crash, so do it like this in this case:
std::string str2 = ""; // initialise to empty string, that is the NULL you are saying I guess
if(str.size() > 20)
str2 = str.substr (20, 25);
// 'str2' will be an empty string

Bounds of std::string::find_first_of

Suppose I have a string foo and I want to search for the second period, if any.
I'm using this code:
std::size_t start = foo.find_first_of('.');
if (start != std::string::npos){
std::size_t next = foo.find_first_of('.', start + 1);
/*and so on*/
I'm wondering if this is well-defined if the first period is at the end of the string.
I think it is since start + 1 will be on the null-terminator, so I'm not in any danger of accessing any memory I shouldn't.
Am I correct?
If the first dot is at the end of the string, it's at index size() - 1.
So then start + 1 == size(), meaning that find_first_of will look in the interval [size(), size()). This is an empty interval, so no memory accesses will be made at all.
There may well not be a null-terminator at that point. (The standard does not guarantee it: c_str() is required to add one if necessary).
But your code is fine in any case. The behaviour on setting a pointer to point to 1-past-an-array is well-defined, so it's permissible to call the function with start + 1 is start is the last character in your string. Internally, a dereference of that pointer will not take place you're outside the region that find_first_of will search.
The C++ Standard does not impose any restriction on the value of the second parameter.
The function tries to calculate an actual position xpos the following way
pos <= xpos and xpos < size()
If it is unable to find such a velue it returns std::string::npos
For example
std::string s( "AB" );
auto pos = s.find_first_of( "A", std::string::npos );
if ( pos == std::string::npos ) std::cout << "Not found" << std::endl;
The output is
Not found

How to use std::stod properly

I am working on writing a simple linear line calculator. For example, a user can enter two equations (strings) such as y=5x+3 and y=-3x+6. The most basic feature of this calculator is that it will return the intersection point of these two lines.
The obstacle I can't seem to figure out is how to parse the string into two pieces of data: the slope, and the y-intercept. This is a simple calculator, so the format of both lines will be y=mx+b, however, both the slope and/or y-intercept may be non-integer numbers (i.e. floats).
I came across a function in the string library called stod, which converts a number in a string to a numerical value (am I understanding this correctly?).
http://www.cplusplus.com/reference/string/stod/
My question is, will this function do the job? If so, how exactly do I use the "idx" parameter? I don't quite understand it.
If this isn't going to work, how can I parse this user-entered data?
both equations are strings (y=mx+b)
m and b have private variables dedicated in storing the decimal value (i.e. double m_ and double b_ are private member variables)
This is how the idx parameter works:
#include <string>
#include <iostream>
int main(void)
{
std::string data = "y=5.9568x+3.14"; //say you have a string like this..
double y, x, m, b;
y = 0;
x = 0;
std::size_t offset = 0; //offset will be set to the length of characters of the "value" - 1.
m = std::stod(&data[2], &offset); //So we want to get the value "5.9568
b = std::stod(&data[offset + 3]); //When we reach this line, offset has a value of 6
std::cout<<b;
return 0;
}
So now you're asking why does it have a value of 6? Well because:
5.9568 is exactly: 6 characters in length. Thus on the next line when we do
b = std::stod(&data[offset + 3]);
we are actually feeding it a pointer to address of x + 3.. and that turns out to be right at the beginning of the 3.14.
In other words it's equivalent to:
std::stod(&data[9]);
So that idx parameter is actually the index/length of the double in characters within the string. If the string is:
str = "3.14159"
Then std::stod(str, &idx) will make idx equal to: 6.
if the string is:
str = "y = 1024.789" then std::stod(&str[4], &idx) will make idx equal to: 8 STARTING FROM &str[4]..
Here's something simple with no error checking to get you started:
Assuming your input string is always exactly of the form y=mx+b and you wish to parse it to obtain the numerical values of m and b you can first tokenize the string with y, =, x, and as delimiters.
An example of a tokenizing function can be found here. Here it is reproduced:
void tokenize(const std::string &str,
std::vector<std::string> &tokens,
const std::string &delimiters)
{
// Skip delimiters at beginning.
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
The first argument is the string to tokenize, the second is a reference to a vector<string> which the function will put the tokens in, and the third argument is a string containing all the delimiter characters. You can use it with the delimiters mentioned above like this:
string s = "y=-3x + 10";
vector<string> tokens;
tokenize(s, tokens, "y=x ");
For the example string above tokens will contain the following strings: -3, +, and 10.
Now you can iterate over tokens and call stod() on each token. You can put the results of stod() in a vector<double>:
vector<double> doubles;
for (vector<string>::iterator iter = tokens.begin(); iter != tokens.end(); ++iter) {
try {
doubles.push_back(stod(*iter)); // size_t* idx is an optional argument
} catch (...) {
// handle exceptions here. stod() will throw an exception
// on the "+" token but you can throw it away
}
}
Now doubles should have exactly 2 elements -- one for the slope and another for the intercept. Assuming the slope came first (the string was of the form y=mx+b instead of y=b+mx) then you can extract them from doubles:
double m = doubles[0];
double b = doubles[1];
Parsing the initial string is more complicated if the user is allowed different forms like y=b+mx (in that case the intercept came first), and much more complicated if the user can enter even stranger (but valid) forms like x*m+b=y (now you can't just assume that the number before the x character is the slope). It's not clear from your question exactly what alternate forms are considered valid, but nonetheless this should get you started.
Finally, as to your question about *idx, stod() puts into it the position of the first character after the number it parsed. This allows you to easily parse multiple numbers in a single string by skipping the number that was just parsed. Using the example at your reference link with some added comments:
std::string orbits ("365.24 29.53");
std::string::size_type sz; // alias of size_t
double earth = std::stod (orbits,&sz);
// sz now holds the position of the first character after 365.24, which is whitespace
// the next call to stod() will start from the sz position
double moon = std::stod (orbits.substr(sz));

Is the integer n in the string s? Is 4 in Ab56c4D? (C++)

Is there a standard function which will return a bool for this?
I'm writing a program that plays the game of life and the user enters two strings, S23 and B3 are examples. In my main loop I just want to check if an integer (the number of living surround cells) is in one of the strings.
Thanks for your help with this question. ;)
http://www.cplusplus.com/reference/string/string/find/
Searches the string for the content specified in either str, s or c, and returns the position of the first occurrence in the string.
Return Value:
The position of the first occurrence in the string of the searched content.
If the content is not found, the member value npos is returned.
First you need to get a string version of the integer value, then you can try to find it in the other string:
std::ostringstream oss;
oss << some_integer;
if (some_string.find(oss.str()) != std::string::npos)
// match...
Loop through the characters in the string and if the character ( (int)cur_char) ) is between 48 and 57 return true.