Is there a way to convert C-format strings for C#

2019-05-27 14:26发布

问题:

So i would like to convert string like this:

"Bloke %s drank %5.2f litres of booze and ate %d bananas"

with a C# equivalent for .Format or .AppendFormat methods

"Bloke {0} drank {1,5:f2} litres of booze and ate {2} bananas"

sorry but i'm not sure if the C# version was correct but u got the idea. The solution does not have to be perfect but cover the basic case.

Thanks & BR -Matti

answered in my other question How to write C# regular expression pattern to match basic printf format-strings like "%5.2f"?

回答1:

You could probably just use StringBuilder.Replace().

StringBuilder cString = new StringBuilder("Bloke %s drank %5.2f litres of booze and ate %d bananas");
cString.Replace("%s","{0}");
cString.Replace("%5.2f", "1,5:f2"); // I am unsure of this format specifier
cString.Replace("%d", "{2}");

string newString = String.Format(cString.ToString(), var1, var2, var3);

Conceivably you could add something like this to as an extension method to String, but I think your biggest problem is going to be the specially formatted specifiers. If it is non-trivial in this aspect, you may need to devise a regular expression to catch those and perform the replace meaningfully.



回答2:

First attempt: this (kinda) ignores everything between a % and one of diouxXeEfFgGaAcpsn and replaces that with a {k} where k goes from 0 to a maximum of 99 (not checked in code: more than 100 % in the input returns a bad format string).

This does not consider the * in a directive special.

#include <string.h>

void convertCtoCSharpFormat(char *dst, const char *src) {
  int k1 = 0, k2 = 0;
  while (*src) {
    while (*src && (*src != '%')) *dst++ = *src++;
    if (*src == '%') {
      const char *percent;
      src++;
      if (*src == '%') { *dst++ = '%'; continue; }
      if (*src == 0) { /* error: unmatched % */; *dst = 0; return; }
      percent = src;
      /* ignore everything between the % and the conversion specifier */
      while (!strchr("diouxXeEfFgGaAcpsn", *src)) src++;

      /* replace with {k} */
      *dst++ = '{';
      if (k2) *dst++ = k2 + '0';
      *dst++ = k1++ + '0';
      if (k1 == 10) { k2++; k1 = 0; }
      /* *src has the conversion specifier if needed */
      /* percent points to the initial character of the conversion directive */
      if (*src == 'f') {
        *dst++ = ',';
        while (*percent != 'f') *dst++ = *percent++;
      }
      *dst++ = '}';
      src++;
    }
  }
  *dst = 0;
}

#ifdef TEST
#include <stdio.h>
int main(void) {
  char test[] = "Bloke %s drank %5.2f litres of booze and ate %d bananas";
  char out[1000];

  convertCtoCSharpFormat(out, test);
  printf("C fprintf string: %s\nC# format string: %s\n", test, out);
  return 0;
}
#endif