I have a Visual Studio 2008 C++ project where I need to parse a string to a structure of c-style character arrays. What is the most elegant/efficient way of doing this?
Here is my current (functioning) solution:
struct Foo {
char a[ MAX_A ];
char b[ MAX_B ];
char c[ MAX_C ];
char d[ MAX_D ];
};
Func( const Foo& foo );
std::string input = "abcd@efgh@ijkl@mnop";
std::vector< std::string > parsed;
boost::split( parsed, input, boost::is_any_of( "@" ) );
Foo foo = { 0 };
parsed[ 1 ].copy( foo.a, MAX_A );
parsed[ 2 ].copy( foo.b, MAX_B );
parsed[ 3 ].copy( foo.c, MAX_C );
parsed[ 4 ].copy( foo.d, MAX_D );
Func( foo );
Here is my (now tested) idea:
#include <vector>
#include <string>
#include <cstring>
#define MAX_A 40
#define MAX_B 3
#define MAX_C 40
#define MAX_D 4
struct Foo {
char a[ MAX_A ];
char b[ MAX_B ];
char c[ MAX_C ];
char d[ MAX_D ];
};
template <std::ptrdiff_t N>
const char* extractToken(const char* inIt, char (&buf)[N])
{
if (!inIt || !*inIt)
return NULL;
const char* end = strchr(inIt, '@');
if (end)
{
strncpy(buf, inIt, std::min(N, end-inIt));
return end + 1;
}
strncpy(buf, inIt, N);
return NULL;
}
int main(int argc, const char *argv[])
{
std::string input = "abcd@efgh@ijkl@mnop";
Foo foo = { 0 };
const char* cursor = input.c_str();
cursor = extractToken(cursor, foo.a);
cursor = extractToken(cursor, foo.b);
cursor = extractToken(cursor, foo.c);
cursor = extractToken(cursor, foo.d);
}
Adding a little test code
template <std::ptrdiff_t N>
std::string display(const char (&buf)[N])
{
std::string result;
for(size_t i=0; i<N && buf[i]; ++i)
result += buf[i];
return result;
}
int main(int argc, const char *argv[])
{
std::string input = "abcd@efgh@ijkl@mnop";
Foo foo = { 0 };
const char* cursor = input.c_str();
cursor = extractToken(cursor, foo.a);
cursor = extractToken(cursor, foo.b);
cursor = extractToken(cursor, foo.c);
cursor = extractToken(cursor, foo.d);
std::cout << "foo.a: '" << display(foo.a) << "'\n";
std::cout << "foo.b: '" << display(foo.b) << "'\n";
std::cout << "foo.c: '" << display(foo.c) << "'\n";
std::cout << "foo.d: '" << display(foo.d) << "'\n";
}
Outputs
foo.a: 'abcd'
foo.b: 'efg'
foo.c: 'ijkl'
foo.d: 'mnop'
See it Live on http://ideone.com/KdAhO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With