RS Game Maker Community
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

 
Расширенный поиск
  Главная  Форум   Вики Блоги FAQ Игры Статьи Примеры Войти Регистрация  
Вики
Все желающие приглашаются редактировать вики. Можете писать о своих (или чужих) играх, размещать туториалы, постить статьи - главное навесить категорию.
Страниц: 1   Вниз
  Печать  
Форматированная строка
0 Пользователей и 1 Гость смотрят эту тему.
Огион
Завсегдатай
****

Репутация: 133
Offline Offline

Сообщений: 992


28 Мая 2013 в 00:23
stringf(format, ...)
Скрипт возвращает форматированную строку.
Строка форматирования имеет вид:
%[флаги][ширина поля][.точность]тип
Скрипт принимает флаги -, +, 0 и « » (пробел). В качестве ширины и точности можно ставить *, чтобы значение бралось из следующего аргумента. Типов переменных два: s и r (строки и действительные числа).
Чтобы написать сам знак процента, напишите %%. А ещё этом в скрипте работает переход на новую строку через \n, а # отображается на экране.

tl;dr: с помощью этого скрипта можно на ходу объединять строки и переменные, приводя их к желаемого виду. Например, чтобы в углу отображался FPS, можно написать: draw_text(0, 0, stringf("FPS: %.r", fps)).
//stringf(format, ...)
var format, final_string, current_argument;
format = argument[0];
final_string ="";
current_argument = 1;
 
var i, anchor, char;
i = 1;
while (i <= string_length(format)) {
    char = string_char_at(format, i);
    anchor = i;
    i += 1;
    if (char != "%") {
        switch (char) {
            case "#":
                final_string += "\#";
                continue;
            case "\":
                if (string_char_at(format, i) == "n") {
                    final_string += "#";
                    i += 1;
                    continue;
                }
                else {
                    final_string += char;
                    continue;                    
                }
            default:
                final_string += char;
                continue;
        }
    }
    if (string_char_at(format, i) == "%") {
        final_string += char;
        i += 1;
        continue;
    }
    ///Считывание флагов///
    var flag_allignleft, flag_showplus, flag_showspace, flag_zeroes, nomoreflags;
    
    flag_allignleft = false;
    flag_showplus = false;
    flag_showspace = false;
    flag_zeroes = false;
    
    nomoreflags = false;
    while (!nomoreflags) {
        char = string_char_at(format, i);
        switch char {
            case "-":
                flag_allignleft = true;
                i += 1;
                break;
            case "+":
                flag_showplus = true;
                i += 1;
                break;
            case " ":
                flag_showspace = true;
                i += 1;
                break;
            case "0":
                flag_zeroes = true;
                i += 1;
                break;
                
            default:
                nomoreflags = true;
                break;
        }
    }
    
    var width, precision;
    width = -1;
    precision = -1;
    
    ///Считывание ширины///
    if (char == "*") {
        if (current_argument + 1 >= argument_count) {
            final_string += "%";
            i = anchor + 1;
            continue;
        }
        width = argument[current_argument];
        current_argument += 1;
        i += 1;
        char = string_char_at(format, i);
    }
    
    if (char != "." ) {
        var digits_string, nomoredigits;
        digits_string = "";
        nomoredigits = false;
        while (!nomoredigits) {
            char = string_char_at(format, i);
            if (char != string_digits(char)) {
                nomoredigits = true;
            }
            else {
                digits_string += char;
                i += 1;
            }
        }
        if (digits_string != "") {
            width = real(digits_string);
        }
    }
    if (char == "." ) {
        precision = 0;
        ///Считывание точности///
        i += 1;
        char = string_char_at(format, i);
        
        if (char == "*") {
            if (current_argument + 1 >= argument_count) {
                final_string += "%";
                i = anchor + 1;
                continue;
            }
            precision = argument[current_argument];
            current_argument += 1;
            i += 1;
            char = string_char_at(format, i);
        }
        
        if (char != ".") {
            var digits_string, nomoredigits;
            digits_string = "";
            nomoredigits = false;
            while (!nomoredigits) {
                char = string_char_at(format, i);
                if (char != string_digits(char)) {
                    nomoredigits = true;
                }
                else {
                    digits_string += char;
                    i += 1;
                }
            }
            if (digits_string != "") {
                precision = real(digits_string);
            }
        }
    }
    
    switch (char) {
        case "s": //Тип s (строка)
            var temp_string;
            temp_string = argument[current_argument];
            current_argument += 1;
            
            if (precision != -1) {
                temp_string = string_copy(temp_string, 0, precision);
            }
            if (width != -1) {
                var tab_size, symbol;
                tab_size = max(0, width - precision);
                
                if (flag_zeroes) {
                    symbol = "0";
                }
                else {
                    symbol = " ";
                }
                    
                if (flag_allignleft) {
                    temp_string = temp_string + string_repeat(symbol, tab_size);
                }
                else {
                    temp_string = string_repeat(symbol, tab_size) + temp_string;
                }
            }
            final_string += temp_string;
            break;
            
        case "r": //Тип r (вещественное число)
            var temp_string, num;
            num = argument[current_argument];
            current_argument += 1;
            
            if (precision == -1) {
                    precision = 6;
            }
            
            temp_string = string_format(num, 0, precision);
            
            if (flag_showspace && num >= 0) {
                temp_string = " " + temp_string;
            }
                
            if (flag_showplus && num >= 0) {
                temp_string = "+" + temp_string;
            }
            if (width != -1) {
            var tab_size, symbol;
                tab_size = max(0, width - string_length(temp_string));
                
                if (flag_zeroes) {
                    symbol = "0";
                }
                else {
                    symbol = " ";
                }
                if (flag_allignleft) {
                    temp_string = temp_string + string_repeat(symbol, tab_size);
                }
                else {
                    temp_string = string_repeat(symbol, tab_size) + temp_string;
                }
            }
            final_string += temp_string;
            break;
            
        default:
            final_string += "%";
            i = anchor;
            break;
    }
    i += 1;
}
return final_string;

UPD Толич сделал свой вариант, который во многом лучше. См. вложения.
Прикреплённые файлы
* format.gml (6.45 Кб - загружено 205 раз.)
Последнее редактирование: 06 Ноября 2014 в 21:01 от Огион
 
Кто-тo
Ветеран форума
*****

Репутация: 81
Offline Offline

Сообщений: 1 112


Ответ № 1 28 Мая 2013 в 01:10
Принимаются следующие флаги: „-“, „+“, „ “, „0“.
С „этими кавычками“ труднее разобрать, особенно при перечислении через запятую. Чем «эти кавычки» плохи?
Огион
Завсегдатай
****

Репутация: 133
Offline Offline

Сообщений: 992


Ответ № 2 28 Мая 2013 в 01:16
А ты сравни: „+“ и «+». «Ёлочки» ещё сильнее давят одиночный символ.
Кто-тo
Ветеран форума
*****

Репутация: 81
Offline Offline

Сообщений: 1 112


Ответ № 3 28 Мая 2013 в 02:28
А "эти"? Или вообще 'эти'?
Огион
Завсегдатай
****

Репутация: 133
Offline Offline

Сообщений: 992


Ответ № 4 28 Мая 2013 в 02:50
Этими я только строки в коде обрамляю. В общем, выделил полужирным. Но пробел всё равно выглядит по-идиотски, тут уж я не знаю, что можно сделать.
Последнее редактирование: 28 Мая 2013 в 03:08 от Ωγιόν
Огион
Завсегдатай
****

Репутация: 133
Offline Offline

Сообщений: 992


Ответ № 5 18 Октября 2014 в 21:40
Обновил скрипт. Исправил, надеюсь, все ошибки. Решил, что real всё же будет правильнее, чем float, так что пишите %r вместо %f. Ещё взаимную замену \n и # интегрировал в скрипт нормально, а не через жопу string_replace. А ещё теперь можно отображать сам знак процента при помощи управляющей последовательности %%.
Правда, скрипт так и остался нечитаемым адом. Простите. Всё равно его никто не использует.
Последнее редактирование: 18 Октября 2014 в 22:09 от Огион
tolich
to ne lich
Ветеран форума
*****

Репутация: 221
Offline Offline

Сообщений: 1 569


moonlite

Ответ № 6 20 Октября 2014 в 14:50
Конечно, хозяин - барин, но вообще-то, формат f означает fixed point, а не float. Это не только о формате данных, а о формате вывода. Ещё есть e и g (соответственно, exponential и general).
И ещё, номера позиций в строках в GM начинаются с 1, а не с 0, как ты думаешь.
temp_string = string_copy(temp_string, 0, precision);
<=должно быть 1, а не 0.

Edit
1) При форматировании строк флаг "0" должен игнорироваться, он только для чисел. У тебя строки дополняются нулями.
2) При форматировании чисел флаг "0" должен дополнять число слева нулями, но знак, при наличии, должен быть ещё левее. У тебя нули выводятся слева от знака.
3) Должно быть запрещено выводить числа, как строки, и строки, как числа. У тебя даже проверки нет.

Я вот переписал скрипт с учётом изложенных замечаний, также добавил вывод целых чисел d. Значение precision определяет минимальное число выводимых цифр, т.е. stringf("10.4d",100) превратится в "    0100".
* format.gml.gz (1.75 Кб - загружено 191 раз.)
Прикреплённые файлы
* format.gml.gz (1.75 Кб - загружено 191 раз.)
Последнее редактирование: 20 Октября 2014 в 18:20 от tolich

Огион
Завсегдатай
****

Репутация: 133
Offline Offline

Сообщений: 992


Ответ № 7 20 Октября 2014 в 22:38
Конечно, хозяин - барин, но вообще-то, формат f означает fixed point, а не float.
Хм, действительно. Но я исходил из того, что в GM этот тип называется real. По этой же причине я отказался от целочисленного типа i, который сам какое-то время использовал.
Не смог открыть твой архив 7-зипом. То есть смог, но получил кашу из символов.
tolich
to ne lich
Ветеран форума
*****

Репутация: 221
Offline Offline

Сообщений: 1 569


moonlite

Ответ № 8 21 Октября 2014 в 10:13
У меня открывает. Возможно, дело в том, что там комментарии в cp1251. На всякий креплю zip, он должен открыться.
Прикреплённые файлы
* format.zip (1.86 Кб - загружено 112 раз.)

Райдо
Старожил
******

Репутация: 89
Offline Offline

Награды:
Легенда сайта
Сообщений: 2 639


Ответ № 9 05 Ноября 2014 в 23:34
А буферами не пробовали? Поскольку в буфере текст в сыром виде, то алгоритм будет устойчив к разницам в кодировке, ибо любая кодировка имеет нижние 127 символов в ASCII, и именно эти символы используются как спецсимволы форматирования. Кстати да, форматированная строка, а не форматная.

tolich
to ne lich
Ветеран форума
*****

Репутация: 221
Offline Offline

Сообщений: 1 569


moonlite

Ответ № 10 06 Ноября 2014 в 00:40
Да, действительно, форматная это которая format.

tolich
to ne lich
Ветеран форума
*****

Репутация: 221
Offline Offline

Сообщений: 1 569


moonlite

Ответ № 11 24 Августа 2019 в 13:04
Заметил ошибку в своей версии, в скриптах string_span и string_break
Вместо:
for(pos=1; pos<string_length(argument1); pos+=1)
должно быть:
for(pos=1; pos<=string_length(argument1); pos+=1)
Иначе если первый подходящий символ последний в строке, результат будет 0.

P.S. Или даже:
for(pos=1; pos<=string_length(argument1); pos++)

Страниц: 1   Вверх
  Печать  
 
Перейти в:  

RSGMC (gmakers.ru) © 2007—2019
Счётчик–@Mail.ru