Posted By

jimfred on 01/29/10


Tagged


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

danfinrud55
khouser


C#, convert a double-null-terminated string to an array of strings.


 / Published in: C#
 

Double-null-terminated strings are sometimes referred to as multistrings - \r\nhttp://stackoverflow.com/questions/268899/how-do-you-convert-multistring-to-from-c-string-collection\r\n\r\nmultistrings used in...\r\nOPENFILENAME::lpstrFilter in common dialogs\r\nRegQueryStringValue\r\nChangeServiceConfig\r\n\r\nThis works somewhat...\r\nstring[] a2 = (new string(Buff)).TrimEnd(\'\0\').Split(\'\0\');\r\n...but includes junk after a double-null.

  1. /// <summary>
  2. /// Convert a double-null terminated string into an array of strings
  3. /// Example usage:
  4. /// char [] buff = new char[];
  5. /// // fill Buff with data calling an API.
  6. /// string[] a = MultistringToStringArray(ref buff); // Find first double-null.
  7. /// </summary>
  8. /// <param name="arg">double-null terminated string</param>
  9. /// <returns>array of strings</returns>
  10. /// Gracefully handle fringe conditions: missing double-null, missing trailing single null,
  11. private static string [] MultistringToStringArray(ref char[] arg)
  12. {
  13. // Search an array of bytes for a double-null before converting to string.
  14. int qty, j;
  15. for ( qty = 0, j = 1; ; qty++, j++)
  16. {
  17. bool done = qty > (arg.Length - 1) || (arg[qty] == 0 && j < arg.Length && arg[j] == 0);
  18. if (done)
  19. {
  20. break;
  21. } // if
  22.  
  23. } // for
  24. string b = new string(arg, 0, qty);
  25. return b.Split(new char[] { '\0' }, 9, StringSplitOptions.RemoveEmptyEntries);
  26. } // lengthDoubleNull
  27.  
  28.  
  29. // More concise but less efficient variation.
  30. private static string [] MultistringToStringArray(ref char[] arg)
  31. {
  32. string s2 = new string(arg); // convert to string - even bytes after \0\0.
  33. int x = s2.IndexOf("\0\0"); // find double-null.
  34. if (x != -1) { s2 = s2.Remove(x); } // remove if found.
  35. return s2.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  36. }
  37.  
  38.  
  39. // test this function. Use Enumerable.SequenceEqual to deep-compare array of strings.
  40. [Conditional("DEBUG")]
  41. private static void MultistringToStringArrayTest()
  42. {
  43. char[] b;
  44.  
  45. // fringe scenario. missing double-null.
  46. b = new char[] { 'a', 'b', 'c' };
  47. Debug.Assert( Enumerable.SequenceEqual(new string[] { "abc" }, MultistringToStringArray(ref b)));
  48.  
  49. // fringe scenario. missing double-null.
  50. b = new char[] { 'a', 'b', 'c', '\0' };
  51. Debug.Assert( Enumerable.SequenceEqual(new string[] { "abc" }, MultistringToStringArray(ref b)));
  52.  
  53. // fringe scenario. missing single-null.
  54. b = new char[] { 'a', 'b', 'c', '\0', '\0', 'a', 'b', 'c' };
  55. Debug.Assert( Enumerable.SequenceEqual(new string[] { "abc" }, MultistringToStringArray(ref b)));
  56.  
  57. // Most common scenario - embedded nulls with a terminating double-null and junk after that.
  58. b = new char[] { 'a', 'b', 'c', '\0', '1', '2', '3', '\0', '\0', 'a', 'b', 'c' };
  59. Debug.Assert( Enumerable.SequenceEqual(new string[] { "abc", "123" }, MultistringToStringArray(ref b)));
  60.  
  61. // fringe scenario. missing double-null.
  62. b = new char[] { 'a', 'b', 'c', '\0', '1', '2', '3', '4', '\0' };
  63. Debug.Assert(Enumerable.SequenceEqual(new string[] { "abc", "1234" }, MultistringToStringArray(ref b)));
  64.  
  65. // common scenario.
  66. b = new char[] { 'a', 'b', 'c', '\0', '1', '2', '3', '4', '\0', 'A', 'B', 'C', '\0' };
  67. Debug.Assert(Enumerable.SequenceEqual(new string[] { "abc", "1234", "ABC" }, MultistringToStringArray(ref b)));
  68.  
  69. }

Report this snippet  

You need to login to post a comment.