PC Review


Reply
Thread Tools Rate Thread

Convert a Widestring to an Ascii String?

 
 
Marc
Guest
Posts: n/a
 
      16th Nov 2007
Hello dear,

I have a string and every second char is a \0. Can I somehow convert it to a
normal string. Or may-be in the underlying code I am doing something wrong,
choose the wrong C# type?

This is my function I am trying to get right:

public static bool GetPrivateProfileSectionAsCS(string appName, string
fileName, out string section)
{
section = null;
if (!System.IO.File.Exists(fileName))
return false;
uint MAX_BUFFER = 32767;
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
uint bytesReturned = GetPrivateProfileSectionW(appName, pReturnedString,
MAX_BUFFER, fileName);
if ((bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
return false;
System.Text.StringBuilder returnedString = new
System.Text.StringBuilder((int)bytesReturned);
//bytesReturned -1 to remove trailing \0
for (int i = 0; i < bytesReturned - 1; i++)
returnedString.Append((char)Marshal.ReadByte(new
IntPtr((uint)pReturnedString + (uint)i)));
Marshal.FreeCoTaskMem(pReturnedString);
section = returnedString.ToString();
section.Replace("\0", ""); // this does not work
return true;
}

And this is how my string section looks like:

"N\0U\0M\0B\0E\0R\0=\0f\0t\0A\0u\0t\0o\0I\0n\0c\0\0\0S\0t\0a\0t\0u\0s\0N\0r\0=\0I\0D\0A\0\0\0P\0a\0t\0N\0a\0m\0e\0=\0N\0o\0t\0U\0s\0e\0d\0\0\0D\0a\0t\0e\0=\0T\0x\0_\0D\0t\0T\0m\0<\0r\0e\0g\0e\0x\0>\0(\00\0[\01\0-\09\0]\0|\0[\01\02\0]\0[\00\0-\09\0]\0|\03\0[\00\01\0]\0)\0-\0(\00\0[\01\0-\09\0]\0|\01\0[\00\01\02\0]\0)\0-\0(\01\09\0|\02\00\0)\0[\00\0-\09\0]\0[\00\0-\09\0]\0<\0/\0r\0e\0g\0e\0x\0>\0\0\0T\0i\0m\0e\0=\0T\0x\0_\0D\0t\0T\0m\0<\0r\0e\0g\0e\0x\0>\0[\00\0-\09\0]\0[\00\0-\09\0]\0:\0[\00\0-\09\0]\0[\00\0-\09\0]\0:\0[\00\0-\09\0]\0[\00\0-\09\0]\0<\0/\0r\0e\0g\0e\0x\0>\0\0\0V\0e\0l\0d\0n\0a\0a\0m\0=\0F\0i\0e\0l\0d\0_\0L\0a\0b\0e\0l\0+\0F\0i\0e\0l\0d\0_\0N\0a\0m\0e\0\0\0C\0l\0i\0n\0i\0c\0=\0T\0s\0t\0l\0\0\0B\0e\0a\0m\0N\0r\0=\0N\0o\0t\0U\0s\0e\0d\0\0\0S\0e\0g\0m\0N\0r\0=\0N\0o\0t\0U\0s\0e\0d\0\0\0T\0e\0r\0m\0i\0n\0a\0t\0e\0=\0N\0o\0t\0U\0s\0e\0d\0\0\0D\0i\0a\0p\0h\0P\0r\0e\0s\0c\0=\0N\0o"


 
Reply With Quote
 
 
 
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      16th Nov 2007
On Nov 16, 12:34 pm, "Marc" <i...@ingcarlease.nl> wrote:
> I have a string and every second char is a \0. Can I somehow convert it to a
> normal string. Or may-be in the underlying code I am doing something wrong,
> choose the wrong C# type?


I don't know the details of GetPrivateProfileSectionW, but you may
well be able to get away with creating a byte[] instead of using
AllocCoTaskMem to return an IntPtr. You can then pass that byte[] into
GetPrivateProfileSectionW and use Encoding.Unicode afterwards.

Otherwise, use Marshal.Copy to copy the data into a byte[], and then
again you can use Encoding.Unicode to turn the data into a string.

If these don't work, it's worth asking on the .interop newsgroup.

Jon
 
Reply With Quote
 
Nicholas Paldino [.NET/C# MVP]
Guest
Posts: n/a
 
      16th Nov 2007
Or, he could just use a definition of GetPrivateProvideSection which
would marshal the string correctly. A declaration that uses bytes in the
parameter doesn't do any good.

The declaration should be:

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
static extern uint GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
[In, Out] char[] lpReturnedString,
uint nSize,
string lpFileName);

The use of the char array is to prevent the marshaling layer from not
sending back all of the characters in the string after finding the first
null character.

It makes it a lot easier than allocating the memory and whatnot (which
should have been placed in a try/finally block, in the case of an
exception).


--
- Nicholas Paldino [.NET/C# MVP]
- (E-Mail Removed)


"Jon Skeet [C# MVP]" <(E-Mail Removed)> wrote in message
news:b34c99c8-a2fa-476b-ac0c-(E-Mail Removed)...
> On Nov 16, 12:34 pm, "Marc" <i...@ingcarlease.nl> wrote:
>> I have a string and every second char is a \0. Can I somehow convert it
>> to a
>> normal string. Or may-be in the underlying code I am doing something
>> wrong,
>> choose the wrong C# type?

>
> I don't know the details of GetPrivateProfileSectionW, but you may
> well be able to get away with creating a byte[] instead of using
> AllocCoTaskMem to return an IntPtr. You can then pass that byte[] into
> GetPrivateProfileSectionW and use Encoding.Unicode afterwards.
>
> Otherwise, use Marshal.Copy to copy the data into a byte[], and then
> again you can use Encoding.Unicode to turn the data into a string.
>
> If these don't work, it's worth asking on the .interop newsgroup.
>
> Jon


 
Reply With Quote
 
Marc
Guest
Posts: n/a
 
      16th Nov 2007

"Nicholas Paldino [.NET/C# MVP]" <(E-Mail Removed)> wrote

> Or, he could just use a definition of GetPrivateProvideSection which
> would marshal the string correctly. A declaration that uses bytes in the
> parameter doesn't do any good.
>
> The declaration should be:
>
> [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
> static extern uint GetPrivateProfileString(


I am using GetPrivateProfileSECTION not GetPrivateProfileSTRING

But I guess the defintion should be:

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
static extern uint GetPrivateProfileSection(
string lpAppName,
[In, Out] char[] lpReturnedString,
uint nSize,
string lpFileName);

And this I am using in my program:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetPrivateProfileSectionW(string lpAppName, IntPtr
lpReturnedString, uint nSize, string lpFileName);

public static bool GetPrivateProfileSectionAsCS(string appName, string
fileName, out string section)
{

So there is a difference, but do not ask me now what is correct.

And there is also this little problem. The section is not one null
terminated string but several. This is in MSDN

"The format of the returned keys and values is one or more null-terminated
strings, followed by a final null character. Each string has the following
form: key=string"

I've already used GetPrivateProfileSTRING, that one was easy. Ok, I will
look into it and thanks for suggestions.


 
Reply With Quote
 
Nicholas Paldino [.NET/C# MVP]
Guest
Posts: n/a
 
      16th Nov 2007
Marc,

Regardless, if you use the character array, then you can parse the
character array, looking for the null characters, and splitting the strings
apart that way.


--
- Nicholas Paldino [.NET/C# MVP]
- (E-Mail Removed)

"Marc" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
>
> "Nicholas Paldino [.NET/C# MVP]" <(E-Mail Removed)> wrote
>
>> Or, he could just use a definition of GetPrivateProvideSection which
>> would marshal the string correctly. A declaration that uses bytes in the
>> parameter doesn't do any good.
>>
>> The declaration should be:
>>
>> [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
>> static extern uint GetPrivateProfileString(

>
> I am using GetPrivateProfileSECTION not GetPrivateProfileSTRING
>
> But I guess the defintion should be:
>
> [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
> static extern uint GetPrivateProfileSection(
> string lpAppName,
> [In, Out] char[] lpReturnedString,
> uint nSize,
> string lpFileName);
>
> And this I am using in my program:
>
> [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
> static extern uint GetPrivateProfileSectionW(string lpAppName, IntPtr
> lpReturnedString, uint nSize, string lpFileName);
>
> public static bool GetPrivateProfileSectionAsCS(string appName, string
> fileName, out string section)
> {
>
> So there is a difference, but do not ask me now what is correct.
>
> And there is also this little problem. The section is not one null
> terminated string but several. This is in MSDN
>
> "The format of the returned keys and values is one or more null-terminated
> strings, followed by a final null character. Each string has the following
> form: key=string"
>
> I've already used GetPrivateProfileSTRING, that one was easy. Ok, I will
> look into it and thanks for suggestions.
>


 
Reply With Quote
 
Marc
Guest
Posts: n/a
 
      19th Nov 2007

"Nicholas Paldino [.NET/C# MVP]" <(E-Mail Removed)>

> Marc,
>
> Regardless, if you use the character array, then you can parse the
> character array, looking for the null characters, and splitting the
> strings apart that way.


Hey thanks, this works:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetPrivateProfileSection(string lpAppName, [In, Out]
char[] lpReturnedString, uint nSize, string lpFileName);
//
public static bool GetPrivateProfileSectionAsCommaText(string appName,
string fileName, out string section)
{
section = "";
uint MAX_BUFFER = 327670;
char[] sectionchar = new char[MAX_BUFFER];
if (!System.IO.File.Exists(fileName))
return false;
uint bytesReturned = GetPrivateProfileSection(appName, sectionchar,
MAX_BUFFER, fileName);
if ((bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
return false;
for (int i = 0; i < bytesReturned; i++)
{
if (sectionchar[i] != (char)0)
section += sectionchar[i];
else
{
if (i != bytesReturned - 1) section += ',';
}
}
return true;
}



>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Convert Ascii string to decimal friend Microsoft VB .NET 8 30th Apr 2009 12:34 PM
[C#] Convert a string in ascii to unicode =?Utf-8?B?RnJlZGR5Ym95?= Microsoft Dot NET Compact Framework 11 23rd Dec 2005 12:40 PM
Convert ascii code to string Daniel Passwater via DotNetMonster.com Microsoft Dot NET Framework Forms 2 28th Nov 2004 02:37 AM
Convert a string to Ascii codes and then back to string again Kai Bohli Microsoft C# .NET 11 8th Jul 2004 03:22 PM
how to convert string to ascii value in C# =?Utf-8?B?R1A=?= Microsoft Dot NET Framework 6 22nd Jun 2004 06:24 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 11:25 AM.