Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

String -> C-like string. Подскажите, как лучше?

241
04 июня 2007 года
Sanila_san
1.6K / / 07.06.2005
Есть протокол SMPP, описывающий взаимодействие между СМС-центром и приложениями, основан он на обмене сущностями под названием Portable Data Unit, по сути это - особым образом отформатированные данные. Важная часть таких юнитов - C-like строки, то есть строки, состоящие из набора байт и заканчивающиеся нулём. Длина таких строк теоретически произвольная. Вот пример такой строки.
 
Код:
53 4D 50 50 33 54 45 53 54 00

Задача - преобразовать строку типа String в С-like String. Язык - VB.NET, фреймворк 2.0.
Идеи, как это сделать:
1. Преобразовать в Memory stream посимвольно, добаавить нулевой байт в конце.
2. Преобразовать в массив символов, добавить нулевой байт в конце.
Сложность в том, что должны быть доступны операции конкатенации и деконкатенации по нулевому байту. Кроме прочего, всё это должно быть преобразуемо в поток для передачи по сети.

Сейчас я склоняюсь к посимвольному преобразованию каждой строки в Stream, с дописыванием при помощи Write и EndWrite, деконкатенацию удобно было бы проводить после преобразования .ToString.
5.1K
05 июня 2007 года
freestyler
102 / / 23.02.2007
А в чём вопрос? Если ты не знаешь как преобразовать символ в 16-вид, то класс Microsoft.VisualBasic.Conversion к твоим услугам( метод Conversion.Hex(char ch)).Потом дописываешь 0, как ты и сказал. Или это медленно. Собственно какая суть вопроса(извините за повторение).
5.1K
05 июня 2007 года
freestyler
102 / / 23.02.2007
Вот код на посимвольный перевод.
Код:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            String str = "I am a pupil";
            str += "\0";
            for (int i = 0; i < str.Length;i++ )
            {
               
                Console.Write(Conversion.Hex(str) + " ");
            }
            Thread.Sleep(10000);
        }    
    }
}
241
06 июня 2007 года
Sanila_san
1.6K / / 07.06.2005
Цитата: freestyler
А в чём вопрос? Если ты не знаешь как преобразовать символ в 16-вид, то класс Microsoft.VisualBasic.Conversion к твоим услугам( метод Conversion.Hex(char ch)).Потом дописываешь 0, как ты и сказал. Или это медленно. Собственно какая суть вопроса(извините за повторение).

Это совсем не то. Conversion.Hex(char ch) преобразует символ в шестнадцатиричное представление. Я привёл пример строки в HEX-виде, поскольку только так понятно отличие С-строк от обычных. То есть, обычные строки начинаются с заголовка, содержащего информауию о длине строки, в простом случае это один байт. С-строки начинаются сразу с первого символа строки, и заканчиваются всегда 0x00. Поэтому я пришёл к мысли, что надо писать в стрим символы и в конце дописывать 0х00. Насколько я понял, при передачи строки в стрим она передаётся целиком вместе с заголовком длины. Или я не прав?

5.1K
06 июня 2007 года
freestyler
102 / / 23.02.2007
А это смотря как передовать.Я кажется понимаю о чём ты. Есть класс StringBuilder; там есть метод Append, которы "дописывает" к твоей строке, то что ты хочешь. Т.е. ты отбрасываешь длину, или как ты выразился первый байт, а потом с помощью этого метода дописываем 0. Или я не прав?
5.1K
06 июня 2007 года
freestyler
102 / / 23.02.2007
А можно так: разбиваем строку посимвольно, кидаем в поток посимвольно, кидаем в конце нуль.Но помоему длина строки не передаётся, а строка в потоке заканчивается нулём. Я так решил потому, что из потока мы можем считать целую строку сразу, а вооще-то надо бы проверить. А считывается до символа конца строки т.е '\0'. Хотя его помоему можно переназначить. Но я не уверен, но посмотрю.
5.1K
06 июня 2007 года
freestyler
102 / / 23.02.2007
Ну ты это и сказал, собственно.
5.1K
07 июня 2007 года
freestyler
102 / / 23.02.2007
Судя по нижеприведённому коду в поток не входят символы типа "длина строки"
Код:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
           
            String path="F:\\test.txt";
            FileStream fs = new FileStream(path,FileMode.OpenOrCreate, FileAccess.ReadWrite);
            StreamWriter sw = new StreamWriter(fs);
            BufferedStream bs = new BufferedStream(sw.BaseStream);
            String str1 = "free";
           
            sw.Write(str1);
            Console.WriteLine(bs.Length);
            Thread.Sleep(5000);
            sw.Close();
            fs.Close();
        }    
    }
}
5.1K
07 июня 2007 года
freestyler
102 / / 23.02.2007
Я ошибся. Длинна строки в поток передаётся.
713
07 июня 2007 года
Ap0k
360 / / 13.03.2006
Marshal.StringToHGlobalAnsi Method
Copies the contents of a managed [COLOR=#0000ff]String[/COLOR] into unmanaged memory, converting into ANSI format as it copies.
Namespace: System.Runtime.InteropServices
Assembly: mscorlib (in mscorlib.dll)
Return Value: The address, in unmanaged memory, to where s was copied, or 0 if a null string was supplied.
Код:
[COLOR=blue]using[/COLOR] [COLOR=blue]namespace[/COLOR] System;
[COLOR=blue]using[/COLOR] [COLOR=blue]namespace[/COLOR] System::Runtime::InteropServices;
 
[COLOR=blue]int[/COLOR] main()
{
    [COLOR=green]// Create a managed string.[/COLOR]
    String^ managedString = [COLOR=maroon]"Hello unmanaged world (from the managed world)."[/COLOR];
    [COLOR=green]// Marshal the managed string to unmanaged memory.[/COLOR]
    [COLOR=blue]char[/COLOR]* stringPointer = ([COLOR=blue]char[/COLOR]*) Marshal::StringToHGlobalAnsi(managedString ).ToPointer();
    [COLOR=green]// Always free the unmanaged string.[/COLOR]
    Marshal::FreeHGlobal(IntPtr(stringPointer));
    [COLOR=blue]return[/COLOR] 0;
}
5.1K
07 июня 2007 года
freestyler
102 / / 23.02.2007
А можно и так:
Код:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;

namespace ConsoleApplication2
{
    class Program
    {
        public static void Main(string[] args)
        {
            string str = "free";
            MemoryStream ms=new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            bw.Write(str);
            byte[] buf = ms.ToArray();
            ms.Dispose();
            Console.WriteLine("For BUF");
            Console.WriteLine("BUFFER LENGHT: {0}",buf.Length);
           
            Console.Write("\n");
            for (int i = 0; i < buf.Length; i++)
            {
                Console.Write("0x{0:X} ", buf);
            }
            Console.Write("\n");
            for (int i = 0; i < buf.Length; i++)
            {
                Console.Write("{0} ", Convert.ToChar(buf));
            }
           
         
            byte[] buf_1 = new byte[buf.Length];
            Array.Copy(buf, 1, buf_1, 0, buf.Length - 1);
            Console.WriteLine("For BUF_1");
            Console.WriteLine("BUFFER_1 LENGHT: {0}", buf.Length);
           
            Console.Write("\n");
            for (int i = 0; i < buf_1.Length; i++)
            {
                Console.Write("0x{0:X} " , buf_1);
            }
            for (int i = 0; i < buf.Length; i++)
            {
                Console.Write("{0} ", Convert.ToChar(buf_1));
            }
           
            Thread.Sleep(5000);
           
        }

    }
}
241
11 июня 2007 года
Sanila_san
1.6K / / 07.06.2005
Цитата: Ap0k
Marshal.StringToHGlobalAnsi Method
Copies the contents of a managed [COLOR=#0000ff]String[/COLOR] into unmanaged memory, converting into ANSI format as it copies.
Namespace: System.Runtime.InteropServices
Assembly: mscorlib (in mscorlib.dll)
Return Value: The address, in unmanaged memory, to where s was copied, or 0 if a null string was supplied.

Ого. Это, ИМХО, паллиативный метод; я полагаю, лучше тогда вообще работать с ArrayList и методами классов System.Text. Кстати, скорее всего так работать лучше всего, поскольку с ArrayList удобнее реализовать функцинальность строк. Есть вариант создать такой класс:

 
Код:
Public Class CStringEmulator
    Inherits ArrayList
    'Здесь у нас будет код, специфический для эмуляции С-строк
End Class
Я думаю, это решение самое лучшее с точки зрения простоты использования и функциональности.
241
12 июня 2007 года
Sanila_san
1.6K / / 07.06.2005
Цитата: freestyler
Я ошибся. Длинна строки в поток передаётся.

Ещё бы она не передавалась. Она по идее не должна передаваться только в том случае, когда читается посимвольно.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог