3

Recently I came across this code in a C# application.

cDataString = Strings.StrConv(cDataString, VbStrConv.Wide);

I understand that the StrConv is a string function of VB. You can call it by including 'using Microsoft.VisualBasic;'.

It is supposed to covert half width japanese characters into full width ones.

My question is: Is there a way to achieve the same WITHOUT using the VB functions and WITHOUT including the VB headers, using only the standard c# functions? I know there are many c# string conversion functions and some of them can convert from unicode to ansi and vice versa and so on. But I am not sure if any of those will directly get the exact same result as the above VB one. So, can this be done in c#?

Thank you for your time and efforts.

Update: I came across this question that was asked 5 years ago. The answers and discussions do show some ways in which it could be done. What I would specifically like to know is that, after 5 years and new versions and what nots, is there a simpler and better way to do this in .NET without depending on VB functions or VB libraries?

Community
  • 1
  • 1
PRinCEKtd
  • 270
  • 3
  • 12
  • I don't think there is such thing as "standard c# functions". AFAIK references to `Microsoft.VisualBasic` is as normal as reference to `Microsoft.CSharp` that is added to C# projects. Maybe this can help http://stackoverflow.com/questions/25149458/convert-fullwidth-to-halfwidth. I personally add reference to `Microsoft.VisualBasic` to almost all of my C# projects, as C# can feel a bit lacking after getting used to VB. – Slai Nov 28 '16 at 01:48
  • Thank you Slai. By standard C# functions, I meant the the common 'System.xxx' .Net functions. It may be true that after getting used to VB you might feel that C# is a bit lacking. But unfortunately, I have no idea of VB.I prefer C# .Net and for certain really old & continuing project, C++ MFC. Its true that the StrConv gets the job done, but I didn't like the 'Microsoft.VisualBasic' thing in the include section, and I don't have any ideas about the functions it provides, and so I wanted to remove it if possible. – PRinCEKtd Dec 01 '16 at 07:36

2 Answers2

2

There is no equivalent function in C#.

If you follow the source code for Microsoft.VisualBasic.dll's StrConv, you'll see it actually p/invokes LCMapString internally similar to the answer you linked.

If you don't want to reference Microsoft.VisualBasic.dll, you could wrap the p/invoke into a helper class or service written in C#, something like this...

// NOTE: CODE NOT TESTED
// Code from John Estropia's StackOverflow answer
// https://stackoverflow.com/questions/6434377/converting-zenkaku-characters-to-hankaku-and-vice-versa-in-c-sharp

public static class StringWidthHelper
{
    private const uint LOCALE_SYSTEM_DEFAULT = 0x0800;
    private const uint LCMAP_HALFWIDTH = 0x00400000;
    private const uint LCMAP_FULLWIDTH = 0x00800000;

    public static string ToHalfWidth(string fullWidth)
    {
        StringBuilder sb = new StringBuilder(256);
        LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_HALFWIDTH, fullWidth, -1, sb, sb.Capacity);
        return sb.ToString();
    }

    public static string ToFullWidth(string halfWidth)
    {
        StringBuilder sb = new StringBuilder(256);
        LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, halfWidth, -1, sb, sb.Capacity);
        return sb.ToString();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    private static extern int LCMapString(uint Locale, uint dwMapFlags, string lpSrcStr, int cchSrc, StringBuilder lpDestStr, int cchDest);
}

Otherwise, you could build a Dictionary to act as a look-up table.

Community
  • 1
  • 1
  • Thanks a lot, rshepp. Rather than a Dictionary, I like your helper class idea better. And thanks a lot for the example code. I will try this idea and see what I can do with it. – PRinCEKtd Dec 01 '16 at 07:39
1

Not a generic solution, but in my particular case (Half-width Japanese katakana ラーメン to Full-width katakana ラーメン), String#Normalize with NFKC option did the job.

Note that this method is not entirely compatible with VB one (e.g. it converts full-width numbers 42 to half-width numbers 42), so you need to select characters to replace like:

// Half-width katakana to Full-width katakana
Regex halfKatakana = new Regex(@"[\uFF61-\uFF9F]+");
cDataString = halfKatakana.Replace(cDataString, (m) => m.Value.Normalize(NormalizationForm.FormKC));
snipsnipsnip
  • 2,268
  • 2
  • 33
  • 34
  • do you have vise versa of this method? i tried to use Normalize(NormalizationForm.FormKC) but it is not working in katakana. – Rayner Pangan Mar 11 '22 at 09:12
  • You can't use Normalize to Full-to-Half conversion since halfwidth katakana are not 'canonical'. I guess you have to resort to OP's VB function `Strings.StrConv`. – snipsnipsnip Mar 12 '22 at 01:09