Convert string Mac address to byte-array - c++

I have a string (std::string) which contains a MAC address in C++, e.g.:
10:10:0F:A0:01:00
I need to convert it to an array of bytes (unsigned char*).
The bytes have to be written from left to right. Does anybody have a function or efficient algorithm for this?

Sorry for necroposting, but just to help others who may still be searching for the answer, there is a standard C way that still can be used in C++ without any reinvention of the wheel. Just man ether_aton or click here.

This'll work. You've tagged this as C++ so I've scrupulously avoided the shorter solution that's possible using the sscanf C method. using namespace std is used here only to shorten the quoted code.
#include <iostream>
#include <sstream>
main() {
unsigned char octets[6];
unsigned int value;
char ignore;
using namespace std;
istringstream iss("10:10:0F:A0:01:00",istringstream::in);
iss >> hex;
for(int i=0;i<5;i++) {
iss >> value >> ignore;
octets[i]=value;
}
iss >> value;
octets[5]=value;
// validate
for(int i=0;i<sizeof(octets)/sizeof(octets[0]);i++)
cout << hex << static_cast<unsigned int>(octets[i]) << " ";
cout << endl;
}

Related

cin doesn't work with typecaset

The following program doesn't compile.
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
char c;
cin >> (int)c; // stat 1
//scanf("%d", &c); //stat 2; this when complied gives warning
cout << c << endl;
}
Q1. How to use cin to accept ASCII value of a character. I want to do it using a char variable.
Q2. If ensured that value input by user lies in the range of character, stat 2 will always produce the desired result.
So you want to be able to input e.g. 97 and for output get 'a'? Then read into an actual int and cast the int variable to a character in the output. I.e. almost the opposite of what you do now:
int c;
std::cin >> c;
std::cout << static_cast<char>(c);
If you want to make sure that the input is a valid character, then use e.g. std::isalpha or one of the other character classification functions.

Parsing and turning a string into a number

I have an input file which I'm reading in with the basic myFile >> variable since I know the format and the format will always be correct. The file I'm reading in is formatted as instruction <num> <num> and to make >> work, I'm reading everything in as a string. If I have 3 variables, one to take in each piece of the line, how can I then turn string <1> (for example) into int 1? I know the string's first and last characters are brackets which need to be removed, then I could cast to an int, but I'm new to C++ and would like some insight on the best method of doing this (finding and removing the <>, then casting to int)
use stringstream
#include <string>
#include <sstream>
#include <iostream>
int main() {
std::string str = "<1>";
int value;
std::stringstream ss(str);
char c;
ss >> c >> value >> c;
std::cout << value;
}
First to get the middle character out you can just do char myChar = inputString.at(1);. Then you can do int myInt = (int)myChar;
Even if you remove the <> characters, your still importing the file content into a string using >> so you still need to cast it to an int. If you have only 1 value, you can follow what Nicholas Callahan wrote in the previous answer, but if you have multiple characters you want to read as int, you dont have a choice but to cast.
You can also resort to sscanf.
#include <cstdio>
#include <iostream>
#include <string>
int main()
{
std::string str = "<1234>";
int value;
sscanf(str.c_str(), "<%d>", &value);
std::cout << value << std::endl;
}

Getting long long with suffix out of istringstream (C++)

How come istringstream can't seem to fully read numeric literals with suffixes?
#include <iostream>
#include <sstream>
using namespace std;
int main() {
long long x = 123ULL; // shows 123ULL is a valid long long literal
istringstream iss("123ULL");
iss >> x;
cout << "x is " << x << endl;
char extra;
iss >> extra;
cout << "remaining characters: ";
while(!iss.eof())
{
cout << extra;
iss >> extra;
}
cout << endl;
return 0;
}
The output of this code is
x is 123
remaining characters: ULL
Is this behavior controlled by the locale? Could anyone point me to clear documentation on what strings are accepted by istringstream::operator>>(long long)?
Yes, it's controlled by the locale (via the num_get facet), but no locale I ever heard of supports C++ language literals, and it would be the wrong place to customize this.
Streams are for general-purpose I/O, and C++ integer literal suffixes are very specialized.
The exact behavior of the default num_get facet is described in the C++11 standard in section 22.4.2.1. The description partially references the strto* family of functions from the C standard library. You can find a somewhat condensed version here:
http://en.cppreference.com/w/cpp/locale/num_get/get

String as a parameter (C++)

Is this example code valid?
std::string x ="There are";
int butterflies = 5;
//the following function expects a string passed as a parameter
number(x + butterflies + "butterflies");
The main question here is whether I could just pass my integer as part of the string using the + operator. But if there are any other errors there please let me know :)
C++ doesn't do automatic conversion to strings like that. You need to create a stringstream or use something like boost lexical cast.
You can use stringstream for this purpose like that:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream st;
string str;
st << 1 << " " << 2 << " " << "And this is string" << endl;
str = st.str();
cout << str;
return 0;
}
A safe way to convert your integers to strings would be an excerpt as follows:
#include <string>
#include <sstream>
std::string intToString(int x)
{
std::string ret;
std::stringstream ss;
ss << x;
ss >> ret;
return ret;
}
Your current example will not work for reasons mentioned above.
No, it wouldn't work. C++ it no a typeless language. So it can't automatically cast integer to string. Use something like strtol, stringstream, etc.
More C than C++, but sprintf (which is like printf, but puts the result in a string) would be useful here.

Problem with re-using a stringstream object

I'm trying to use safe practices in handling input with numbers only in C++, so I use a stringstream object as so:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int first, second;
string input;
stringstream sstream;
cout << "First integer: ";
getline(cin, input);
sstream.str(input);
sstream >> first;
cout << first << endl; //display user input in integers
cout << "Second integer: ";
getline(cin, input);
sstream.str(input);
sstream >> second;
cout << second << endl; //display user input in integers
getline(cin, input); //pause program
return 0;
}
However, the second time around it seems to give the variable 'second' an arbitrary value. This is the output:
First integer: 1
1
Second integer: 2
2293592
If I declare two stringstream objects and use them respectively for both variables it seems to work fine. Does this mean that I cannot re-use a stringstream object in the way I'm trying to do? In my real program I intend to handle much more than two input values from the user, so I just want to make sure if there's another way instead of making multiple stringstream objects. I doubt it's of great relevance but I'm on Windows XP and I'm using MinGW as my compiler.
I greatly appreciate any help.
Use sstream.clear(); after sstream >> first;.
You need to reset the state of the stringstream. Generally, this involves two steps: clearing the buffer:
sstream.str("");
and resetting the error state flags:
sstream.clear();
If you don't clear the buffer, if you get an input like "123abc" then "abc" will still be in the stream when you try to read from it the next time.
You should also make sure to test the fail state of the stream (sstream.fail()) to ensure that the extraction was successful. If you want to be sure that the user only entered an integer (i.e., you want to prevent the user from inputting, say, "123abc", then you should test to make sure sstream.eof() is true.
A better way to do this conversion between datatypes would be to use boost::lexical_cast.
Info and examples can be found at the Boost Site.
Below is an example of doing an int to string conversion and back (string to int) such as what you're doing in your program.
#include <string>
#include <boost/lexcal_cast.hpp>
int main(int argc, char *argv[])
{
int i = 42;
std::string s = boost::lexical_cast<std::string>(i);
int j = boost::lexical_cast<int>(s);
return 1;
}
cout << "First integer: ";
getline(cin, input);
sstream.str(input);
sstream >> first; // state of sstream may be eof
cout << "Second integer: ";
getline(cin, input);
sstream.str(input);
sstream.clear(); // clear eof state
sstream >> second; // input from sstream