IPB

Добро пожаловать, гость ( Вход | Регистрация )

9 Страниц V « < 7 8 9  
Reply to this topicStart new topic
> Delphi, Asm, C, WinAPI, PHP, ..., FAQ
Siberian GRemlin
Jul 2 2020, 18:29
Сообщение #161


Advanced Member
***

Группа: CTPAX-X
Сообщений: 528
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



В игре выводится количество денег с разделением порядков запятыми. В ЕХЕ упоминается формат вывода
CODE
%0lld
CODE
%03lld
Как я понимаю, это оно. Есть ли формат вывода с разделением порядков пробелами?

Нужно, чтобы было 1,234,567, а стало 1 234 567.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 2 2020, 19:03
Сообщение #162


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,332
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 310 раз(а)



Это слегка не так работает.
%d - вывести digit
%ld - вывести long digit (для архитектур, где размер int больше long, например int 16, а long 32)
%lld - вывести long long digit (как правило int 64)

%0lld - тоже самое что и %lld (символ один и не указан размер)
%03lld - тоже самое, что %03d (выравнять тремя нулями слева, если число меньше), но для int64

CODE
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(void) {
ULARGE_INTEGER x;
  x.QuadPart = 1;
  printf("%0lld\n", x.QuadPart); // будет просто 1
  printf("%03lld\n", x.QuadPart); // будет 001
  return(0);
}

В сях нет стандартных функций для разделения тысяч, чтобы из 1234567 сделать 1,234,567 или 1 234 567. Боюсь тебе придётся вручную искать код который это делает. Попробуй поискать по работе со строками и символом 0x2C (запятая). Ставлю на то, что как раз твои строки и работают с числами - смотри где они используются.
"%03lld" нужно чтобы у тебя числа менее тысячи добивались нулями: 3007 => 3,007, а не 3,7.
"%0lld" - это остаток в левой части, в примере 3007 - это будет тройка, т.к. её добивать нулями не нужно.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Feb 17 2021, 13:57
Сообщение #163


Advanced Member
***

Группа: CTPAX-X
Сообщений: 528
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Нашёл. Число выводится несколькими строками, затем склеивается со вставкой запятой в одну строку и выводится на экран. Почему-то я сначала думал, что это стандартная процедура вывода, и поленился сразу в IDA поискать.

Помню, что десятичный разделитель можно было выводить и запятой, и точкой. Но после школы я этим никогда не пользовался.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Feb 17 2021, 18:27
Сообщение #164


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,332
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 310 раз(а)



QUOTE(Siberian GRemlin @ Feb 17 2021, 13:57) *
Помню, что десятичный разделитель можно было выводить и запятой, и точкой. Но после школы я этим никогда не пользовался.
В Delphi есть глобальная переменная DecimalSeparator, которой можно присвоить '.' или ',' в зависимости от того что тебе в качестве разделителя нужно. Если не ошибаюсь, это влияет на функции типа StrToFloat(), FloatToStr() и прочие. В сях, конечно, ничего подобного нет.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Feb 26 2021, 05:30
Сообщение #165


Advanced Member
***

Группа: CTPAX-X
Сообщений: 528
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Рано я радовался. Хоть я и заменил удачно запятую на пробел, и в игре это стало отображаться, но оказалось, что игра в основной части вылетает, так как эта переменная с запятой, видимо, используется не только там.

Кто-нибудь может глянуть код на асме функции склейки этих «%03lld» с запятой и убрать из неё прибавление запятой?

Игра Win64. Работу оплачу.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Feb 26 2021, 11:23
Сообщение #166


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,332
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 310 раз(а)



QUOTE(Siberian GRemlin @ Feb 26 2021, 05:30) *
Рано я радовался. Хоть я и заменил удачно запятую на пробел, и в игре это стало отображаться, но оказалось, что игра в основной части вылетает, так как эта переменная с запятой, видимо, используется не только там.

Кто-нибудь может глянуть код на асме функции склейки этих «%03lld» с запятой и убрать из неё прибавление запятой?

Игра Win64. Работу оплачу.
Вышли мне на почту исполняемый файл игры, я его могу в статике посмотреть. И ещё приложи к нему:
fc /b old.exe new.exe >file.txt
Чтобы было понятно что ты там и где менял (меня интересует только место где ты пробел на запятую заменил).
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 2 2022, 14:13
Сообщение #167


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,332
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 310 раз(а)



Про ограничение у имён файлов.
Мы все прекрасно знаем, что есть программы, которые не работают с русскими или не английскими буквами. На самом деле ограничений гораздо больше, если программа написана не очень хорошо. Ниже будет приведён список из множества тех, с которыми можно так или иначе столкнуться.

1) Программы работающие корректно только с английскими буквами в пути и именах файлов.
Вернее сказать, работают они корректно только с цифрами "0".."9", английскими буквами "A..Z" (маленькими и большими) и символом подчерк "_". Ещё можно использовать минус-тире "-", тильду "~" и много чего ещё, но не стоит, потому что, как минимум, с тире есть проблемы из-за того что некоторые не особо умные программы, сами парсят командную строку, причём криво, и видя где-то "-" считают что это начало ключа командной строки. Что до не английских букв (русских, немецких и других языков) - так у них в ANSI кодировке код символа более 127, что такие программы считают за мусорные и обрубают строку по первому такому символу.

2) Программы работающие корректно только с именами без пробелов (подмножество предыдущих).
Аналогичная предыдущей ситуация, когда кривой парсер командной строки считает пробел как разделитель аргументов. Поэтому исключайте из пути пробелы в имени каталогов и файлов.

3) Программы Windows работающие с ограничением в MAX_PATH (260) символов.
Причём, я не помню, вроде бы, MAX_PATH - это включая завершающий ноль, так что, на самом деле, есть только 259 символов. Суть такова: если путь до программы или каталога более MAX_PATH символов, то программа может либо вылететь с ошибкой, либо не запуститься вообще. Чтобы было понятно в чём проблема - большинство функций Windows работающих с файлами и каталогами, типа получения полного пути текущего каталога, принимают два аргумента: буфер и его размер в символах. Можно сделать путь длиннее MAX_PATH, но тогда нужно сперва вызывать функцию чтобы узнать сколько символов нужно, затем выделять память, ещё раз вызывать чтобы уже прочитать в буфер, а после использования этот буфер удалить, чтобы память не текла. Поэтому в 95% случаев (а то и в 99%) разработчики создают на стеке статический буфер в MAX_PATH символов и его используют. При этом некоторые функции, типа GetModuleFileName() (см. документацию в MSDN и пометки о её работе в Windows XP и более младших системах) даже не возвращают нужного размера буфера, так что их приходится вызывать увеличивая размер буфера "на глаз", пока не останется неиспользуемое место в конце.

4) Программы для DOS запущенные в Windows XP / Me / 98 - ограничение в 64 символа.
Аналогичная предыдущей ситуация. В 64 символа, вроде бы, входит также и нулевой, так что есть только 63 для пути с именем файла. Тут, правда, всё во много раз хуже из-за того, что в функциях DOS передавался только буфер, без его размера. При этом Windows пишет туда путь даже если он более 64 символов, что, как правило, приводит к разрушению стека и вылету программы с фатальной ошибкой.

5) Ограничение на имя каталога и файла для DOS в 8.3 (8 символов на имя, точка и ещё 3 на расширение).
Иными словами такой путь:
C:\Program Files\My Files\New File List.txt
Превратится во что-то типа такого для DOS приложения:
C:\PROGRA~1\MYFILE~1\NEWFIL~1.TXT
А если сделать, например, вот такой путь:
C:\PROGRAMS\MY_FILES\FILELIST.NEW
То он будет одинаковай при его указании как в DOS, так и в Windows и проблем не создаст.
А ещё обратите внимание, что в DOS используются только заглавные английские буквы в именах файлов, а также там почему-то, в отличие от Windows, дополнительно запрещены символы "[" и "]" в имени.

Большинство из описанных выше проблем решаются вот таким простым пакетным файлом "RUNSHORT.BAT":
CODE
@echo off
subst Z: .
Z:
program.exe
subst Z: /d

Виртуальный диск Z: можно заменить на любой другой, как и имя запускаемой программы "program.exe". Обратите внимание, что при создании виртуального диска (первый subst) в конце стоит точка - указатель на текущий каталог (откуда был запущен .BAT файл). Для использования нужно положить "RUNSHORT.BAT" в каталог программы рядом с "program.exe" и запустить.

И последнее - не забывайте, что русское (в общем случае не английское или с произвольными символами) имя пользователя в системе тоже может вызвать проблемы (ссылка), т.к. оно входит в часть пути до временного каталога %TEMP% и %TMP%.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 1 2022, 16:13
Сообщение #168


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,332
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 310 раз(а)



Обсуждали когда-то давно в этой теме код и я такой спрашиваю:
QUOTE(-=CHE@TER=- @ Jul 10 2007, 12:51) *
3) MUTEX обязательно должен называться '851137EC-3D96-4EA6-817B-30969CCF477B' или можно своё имя сунуть?..
На что мне отвечают:
QUOTE(Xplorer @ Jul 10 2007, 13:54) *
Можно и своё.
Но никто не объяснил, почему это хитровыделанное имя лучше.
Дело в том, что GUID - это всегда уникальное имя.
Если, конечно, оно не написано абы как, а создано специальной программой, по специальному алгоритму.
У кого стоит Microsoft Visual Studio 6 (1998), то там в утилитах нужная программа точно есть - называется "Create GUID":
C:\Program Files\Microsoft Visual Studio\Common\Tools\GUIDGEN.EXE
Кому лень искать и ставить, то есть аналоги в Интернете (первое что вышло в Google за запросу "create unique guid online"):
- https://www.guidgen.com/ - утверждается, что делает это также, как и Microsoft
- https://www.guidgenerator.com/
Наверное именно поэтому в том же Far Manager последних версий (в смысле, в версии 3.x точно, может и в 2.x - не проверял) для идентификации плагинов, а также других вещей (типа диалоговых окон) используются именно GUID'ы.
Кому интересно к чему приводит попытка назвать что-то простым именем: Two bugs for the price of one.
В статье, правда, всё несколько проще, т.к. имя для CreateEvent() можно, вообще, не задавать (указать как NULL), если планируется работать только внутри одного процесса и есть другие способы (помимо имени) для передачи дескриптора между разными частями программы.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

9 Страниц V « < 7 8 9
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 1st December 2022 - 16:06