Как убрать аоследние 4 символа из переменной?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
el-niko
Новичок
Новичок
Аватара пользователя
 
Сообщения: 44
Зарегистрирован: 17.09.2004 (Пт) 20:15
Откуда: Елец

Как убрать аоследние 4 символа из переменной?

Сообщение el-niko » 19.09.2004 (Вс) 17:48

Как убрать аоследние 4 символа из переменной? Например было "54321", а должно остаться "5".

Подскажите пожалуйста...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 19.09.2004 (Вс) 17:59

Это шутка, да? :roll:
s=left$(s,len(s)-4)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 19.09.2004 (Вс) 17:59

f$=left(f$,len(f)-4)

PATRIOT_kz
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 105
Зарегистрирован: 14.09.2004 (Вт) 21:09
Откуда: Павлодар, Казахстан

Сообщение PATRIOT_kz » 19.09.2004 (Вс) 18:07

x = "54321"
x$=left(x$,len(x)-4)
:lol: :lol: :lol: :lol: :lol:
Press any key . . .

Q2W
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 745
Зарегистрирован: 31.01.2004 (Сб) 20:46
Откуда: Питер

Сообщение Q2W » 22.09.2004 (Ср) 13:25

Ну давайте все по несколку раз одно (ну почти) и тоже понапишем.
Кстати, f$ отличается от f также как x$ от x => получается что текст с обрубленными 4-мя символами мы пмшем в новую переменную.
Я знаю верный путь

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 22.09.2004 (Ср) 14:14

для больших строк это лучший вариант:
Private Declare Sub CopyLng Lib "kernel32" Alias "RtlMoveMemory" _
        (ByVal pDst As Long, pSrc As LongOptional ByVal Bytes As Long = 4)

Private Sub Form_Load()
    Dim s As String
    s = "12345"
    CopyLng StrPtr(s) - 4, Len(s) - 4
    MsgBox "s=" & s
End Sub

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.09.2004 (Ср) 14:46

Hell /HiLevel Bot/ писал(а):Ну давайте все по несколку раз одно (ну почти) и тоже понапишем.
Кстати, f$ отличается от f также как x$ от x => получается что текст с обрубленными 4-мя символами мы пмшем в новую переменную.

Ты не прав - это одно и то же.
Легко проверить -
Код: Выделить всё
Private Sub Main()
x$ = "54321"
Debug.Print x
End Sub
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.09.2004 (Ср) 14:49

marvan писал(а):для больших строк это лучший вариант:

Ага, и память будет течь ручьём...
Изображение

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 22.09.2004 (Ср) 15:09

Ага, и память будет течь ручьём...

2tyomitch
Пустые слова. Обоснуй!

Q2W
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 745
Зарегистрирован: 31.01.2004 (Сб) 20:46
Откуда: Питер

Сообщение Q2W » 22.09.2004 (Ср) 15:19

x = "54321"
x$=left(x$,len(x)-4)


Typa-declaration character does not match declarated data type
Я знаю верный путь

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.09.2004 (Ср) 16:09

Hell /HiLevel Bot/ писал(а):
x = "54321"
x$=left(x$,len(x)-4)

Typa-declaration character does not match declarated data type

Правильно.
А перед этим ты писал(а):получается что текст с обрубленными 4-мя символами мы пмшем в новую переменную

Признаёшь, что был неправ и что переменная одна?
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.09.2004 (Ср) 16:11

marvan писал(а):
Ага, и память будет течь ручьём...

2tyomitch
Пустые слова. Обоснуй!

Обосновка: освобождаться будет на 8 байт меньше памяти, чем выделялось.
Изображение

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 22.09.2004 (Ср) 16:41

2tyomitch
спасибо за замечание,ошибку осознал
тогда так:
l=Len(s)
CopyLng StrPtr(s) - 4, l - 4
MsgBox "s=" & s
CopyLng StrPtr(s) - 4, l

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 22.09.2004 (Ср) 17:06

To marvan:
Ниже на 4 байта от начала строки лежит размер строки в БАЙТАХ, поэтому нужно удваивать и не писать отрицательные значения.
Код: Выделить всё
    l = 2 * (Len(s) - 4)
    If l < 0 Then l = 0
    CopyLng StrPtr(s) - 4, l


To tyomitch:
Никакой потери памяти не будет.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 22.09.2004 (Ср) 17:40

2Vi
а про размер в байтах я совсем забыл, забавно что строка в примере размером в один байт - работала нормально. :)
но если перед удалением строки не восстанавливать её размер - почему
Никакой потери памяти не будет?
я смотрел - там идёт вызов OLEAUT32.SysFreeString - и он не в курсе про оригинальный размер нашей строки.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 22.09.2004 (Ср) 17:57

Почему не будет потери памяти? Потому что длина выделенного блока под строку лежит в другом месте.

Счетчик символов BSTR или VB-шный String - это простой счетчик, который к исходной длине никакого отношения не имеет. Это видно хотя бы потому, что строка, имеющая 0 символов, занимает место в динамической куче и правильно удаляется.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.09.2004 (Ср) 18:04

Vi писал(а):Это видно хотя бы потому, что строка, имеющая 0 символов, занимает место в динамической куче и правильно удаляется.

Не аргумент - там всегда выделяется/удаляется 4+2*длина байт, т.е. 0-символьная строка, что логично, занимает 4 байта. И правильно удаляется.
Изображение

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 23.09.2004 (Чт) 7:04

Не аргумент - там всегда выделяется/удаляется 4+2*длина байт, т.е. 0-символьная строка, что логично, занимает 4 байта. И правильно удаляется.

Хорошо. Переформулируем... Когда в первый раз выделяется память под строку, всегда указывается ее желаемый размер. Этот размер, действительно, не меньше 4+2*(количество байт+1), т..к. формат BSTR такой: 4 байта счетчика + N двойных байт символов + 1 двойной 0. И когда система выделила этот блок, то его размер уже не определяется счетчиком строки. Мы не можем произвольно увеличить этот счетчик, но уж уменьшить (до нуля) никто не воспрещает. И даже обратно восстановить его. Во всяком случае, эти манипуляции не влияют на выделение/освобождение памяти - ничего не потеряется.

Есть такая функция SysReAllocStringLen, которая может продемонстрировать поведение счетчика.
Код: Выделить всё
Private Declare Function SysReAllocStringLen Lib "oleaut32" _
            (ByVal Destination As Any, ByVal Source As Long, ByVal Length As Long) As Long

Private Sub Form_Load()
    Dim s As String, sz As Long
    Dim oldadr As Long, newadr As Long, newadr2 As Long, newadr3 As Long, newadr4 As Long
    s = "1234567"
    sz = Len(s)

    oldadr = StrPtr(s)
   
    SysReAllocStringLen VarPtr(s), 0, sz - 4 ' уменьшим
    newadr = StrPtr(s)
   
    SysReAllocStringLen VarPtr(s), 0, sz ' восстановим
    newadr2 = StrPtr(s)

    SysReAllocStringLen VarPtr(s), 0, sz + 4 ' увеличим немного
    newadr3 = StrPtr(s)

    SysReAllocStringLen VarPtr(s), 0, sz + 24 ' увеличим еще
    newadr4 = StrPtr(s)

    Debug.Print Hex(oldadr), Hex(newadr), Hex(newadr2), Hex(newadr3), Hex(newadr4)
End Sub
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Q2W
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 745
Зарегистрирован: 31.01.2004 (Сб) 20:46
Откуда: Питер

Сообщение Q2W » 23.09.2004 (Чт) 9:43

tyomitch писал(а):
Hell /HiLevel Bot/ писал(а):
x = "54321"
x$=left(x$,len(x)-4)

Typa-declaration character does not match declarated data type

Правильно.
А перед этим ты писал(а):получается что текст с обрубленными 4-мя символами мы пмшем в новую переменную

Признаёшь, что был неправ и что переменная одна?


Лана-лана признаю, но пример от PATRIOT_kz всё-равно не рабочий.
Я знаю верный путь

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.09.2004 (Чт) 10:19

Hell /HiLevel Bot/ писал(а):Лана-лана признаю, но пример от PATRIOT_kz всё-равно не рабочий.

Безусловно нерабочий, этот патриот вообще за базар не отвечает и пишет всякую чушь.
Изображение

PATRIOT_kz
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 105
Зарегистрирован: 14.09.2004 (Вт) 21:09
Откуда: Павлодар, Казахстан

Сообщение PATRIOT_kz » 23.09.2004 (Чт) 11:14

слышь ты "tyomitch" - винни-пух.

Ты в дудку не гуди, а форум существует ещё чтобы по прикалываться! Я же не ты - писсимист и фашист проклятый.
Press any key . . .

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.09.2004 (Чт) 15:27

PATRIOT_kz писал(а):слышь ты "tyomitch" - винни-пух.

Ты в дудку не гуди, а форум существует ещё чтобы по прикалываться! Я же не ты - писсимист и фашист проклятый.

Второй повод забанить патриота...
:twisted:
Изображение

kazah_
Обычный пользователь
Обычный пользователь
 
Сообщения: 99
Зарегистрирован: 13.01.2003 (Пн) 18:37
Откуда: Russia

мдя

Сообщение kazah_ » 23.09.2004 (Чт) 15:36

Так вот... что бы выполнить эту операцию сушествует несколько простейших способов:

Str=Left(Str,len(str)-4)
************************
Str=mid(Str,1,len(Str)-4)

**********
dim Str2 as string
Str2=""
for i=1 to len(Str)
str2=str2+mid(Str,i,1)
next

**********
Выбирай любой!
Mr DEN - THE WAY YOU KNOW / Мр. ДЕН - Ваш Путь к Познанию!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.09.2004 (Чт) 15:42

А причем тут последний вариант? Ему же не скопировать строку надо.
Lasciate ogni speranza, voi ch'entrate.

kazah_
Обычный пользователь
Обычный пользователь
 
Сообщения: 99
Зарегистрирован: 13.01.2003 (Пн) 18:37
Откуда: Russia

Сообщение kazah_ » 23.09.2004 (Чт) 15:47

alibek писал(а):А причем тут последний вариант? Ему же не скопировать строку надо.

потом можно перевести ее обратно str=str2
Mr DEN - THE WAY YOU KNOW / Мр. ДЕН - Ваш Путь к Познанию!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.09.2004 (Чт) 15:56

Ему не надо str, ему надо str без последних четырех символов.
Lasciate ogni speranza, voi ch'entrate.

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 23.09.2004 (Чт) 15:58

А что, простое решение типа

Код: Выделить всё
st = left(st, len(st)-4)


Никому не катит? Или это, типа, слишком просто?



Хм. Тем более что оно уже и предлагалось кажется :)



PATRIOT_kz

Для поприкалываться - существует отдельный форум, типа Треп. В остальных форумах отвечают по делу. И потом, выбирай выражения все таки.

kazah_
Обычный пользователь
Обычный пользователь
 
Сообщения: 99
Зарегистрирован: 13.01.2003 (Пн) 18:37
Откуда: Russia

Re

Сообщение kazah_ » 23.09.2004 (Чт) 16:05

alibek писал(а):Ему не надо str, ему надо str без последних четырех символов.


Да и после

dim Str2 as string
Str2=""
for i=1 to len(Str)
str2=str2+mid(Str,i,1)
next

Str=Str2 однозначно будет то что ему нада.... :) Наворот, ненужный зато мозги позрядились...
Mr DEN - THE WAY YOU KNOW / Мр. ДЕН - Ваш Путь к Познанию!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Re

Сообщение alibek » 23.09.2004 (Чт) 16:07

kazah_ писал(а):Наворот, ненужный зато мозги позрядились...

Не сказал бы, что это упражнение для мозгов. Упражнением была бы работа с памятью (CopyMemory) или использование API. А это ерунда (не говоря уж о том, что цикл должен был идти до Len(str)-4).
Lasciate ogni speranza, voi ch'entrate.

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 23.09.2004 (Чт) 16:17

да не пользуйте что хотите
по результатам теста соотношение скоростей ниже приведённых функций 2:3:4
CopyLng StrPtr(s) - 4, LenB(s) - 8
s = Left$(s, Len(s) - 4)
s = Mid$(s, 1, Len(s) - 4)

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9

    TopList  
cron