0

I want to convert the data in the string KeyData (which is present is <eg2keydata> attribute) to *. But it always takes the first instance of keyData in the string msg. How can I get the particular instance everytime I want to convert? I am new to this and I am unable to debug it.I am not sure about about the for loop. Anyone please help me find the mistake.Thanks!!

  const std::string& msg = "<PolicyAction><ManualKeyPolicyAction><TransformData SPI=\"1219546177\"><eg1KeyData Protocol=\"abc\" KeyLength=\"64\" KeyData=\"d789c\"></eg1KeyData><eg2KeyData Protocol=\"hm\" KeyLength=\"64\" KeyData=\"4328a036abfcf5e9\"></eg2KeyData><Tunne<PolicyAction><ManualKeyPolicyAction><TransformData SPI=\"1219546177\"><eg1KeyData Protocol=\"aes-cbc\" KeyLength=\"64\" KeyData=\"d789c\"></eg1KeyData><eg2KeyData Protocol=\"hmac-sha1-96\" KeyLength=\"64\" KeyData=\"4328a03\"></eg2KeyData><SaltData ";
  std::size_t search1 = msg.find("<eg2KeyData");
  const std::string from1 = "KeyData=\"";
  const std::string to1 = "\"></eg2KeyData>";
  std::size_t endpos1 = msg.find(to1);
  std::string s = msg;
  std::size_t l1 = 0;
  if (msg.find("<eg2KeyData") != std::string::npos)
  {
      l1 = msg.find("KeyData=\"",search1);

    if (l1 != 0)
    {
      std::size_t r1 = endpos1 - l1 - from1.length();
      s.replace(l1 + from1.length(), r1, r1, '*');
    }
  }
  std::cout << s;
leenvr
  • 3
  • 2
  • 1
    If you want to parse XML data, why not use an XML parser? There's no shortage of ones to choose from. – Rook May 29 '17 at 11:46
  • But my task is to do it in c++. I want to know how to find all the occurances of a substring using the find command,not just the first occurance. – leenvr May 29 '17 at 11:51
  • I'll point out that pure C++ XML parsers do exist (google's first hit, [tinyxml](https://github.com/leethomason/tinyxml2/blob/master/tinyxml2.cpp)), and parsing XML data yourself, the hard way is a terrible, terrible idea. Feel free to pass it on to the person setting you the task, who should know better. – Rook May 29 '17 at 11:58
  • What you're trying to do needs some serious parsing. If you still want to use an ad-hoc solution, see [this](https://stackoverflow.com/questions/4034750/find-all-a-substrings-occurrences-and-locations). – zdf May 29 '17 at 12:00
  • Your XML data is still malformed. There's stuff like ` – Rook May 29 '17 at 15:24

1 Answers1

0

Most important note first: not using an XML library to do this for you is madness. Trying to do this properly for complex data without using something that understands the XML format is a very, very bad idea.


If you want to find the next instance of a substring you've just found, you just need to tell find where you want to start searching from, eg.

const std::string& msg = "<PolicyAction><ManualKeyPolicyAction><TransformData SPI=\"1219546177\"><eg1KeyData Protocol=\"abc\" KeyLength=\"64\" KeyData=\"d789c\"></eg1KeyData><eg2KeyData Protocol=\"hm\" KeyLength=\"64\" KeyData=\"4328a036abfcf5e9\"></eg2KeyData><Tunne<PolicyAction><ManualKeyPolicyAction><TransformData SPI=\"1219546177\"><eg1KeyData Protocol=\"aes-cbc\" KeyLength=\"64\" KeyData=\"d789c\"></eg1KeyData><eg2KeyData Protocol=\"hmac-sha1-96\" KeyLength=\"64\" KeyData=\"4328a03\"></eg2KeyData><SaltData ";

size_t p = msg.find("KeyData=");

while (p != std::string::npos)
{
  std::cout << p << " ";
  p = msg.find("KeyData=", p + 1);
}

std::cout << std::endl;

which then gives the result

111 181 342 422

You can then search for the next two instances of the string \", and use those positions to calculate the beginning and end points of the text you want to alter.

Just read the docs! http://en.cppreference.com/w/cpp/string/basic_string/find

Alternatively, you might consider using a regular expression:

std::regex r("KeyData=\\\"([a-z0-9]+)\\\"");

for (auto i = std::sregex_iterator(msg.begin(), msg.end(), r); i != std::sregex_iterator(); i++)
  std::cout << i->position() << " ";

std::cout << std::endl;

This gives the same result. I'm not going to go into the details of how to use regular expressions here though.

http://en.cppreference.com/w/cpp/regex

Rook
  • 5,734
  • 3
  • 34
  • 43
  • This works if there is only one occurance of . what if i have multiple occurances of – leenvr May 29 '17 at 12:18
  • @leenvr unless you can give actual examples of source data, and actual examples of what you want to find, we will just have to guess what you want. I have answered your question as it currently stands. If this isn't the answer you wanted, you will have to edit your question so that it _actually asks what you want_. – Rook May 29 '17 at 14:48
  • sorry for not giving the correct source string. I have edited my code. In the updated code,Can you please help me convert the KeyData in eg2KeyData at both the places in the string – leenvr May 29 '17 at 15:01
  • @leenvr I've made a very small edit to my code to use a while loop. The same fundamental technique is being used. All positions of `KeyData` are returned. Is this what you wanted? – Rook May 29 '17 at 15:07