Продвинутая работа со строками в Pawn

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

Строки - основа работы с данными. Разберем продвинутые техники.

Форматирование с условиями
Код:
FormatPlayerMessage(playerid, message[])
{
    new string[256], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    // Разные форматы для разных групп
    if(PlayerInfo[playerid][pAdmin] > 0)
    {
        format(string, sizeof(string), "[АДМИН] %s: %s", name, message);
    }
    else if(PlayerFaction[playerid][pFaction] != -1)
    {
        format(string, sizeof(string), "[%s] %s: %s", 
            FactionData[PlayerFaction[playerid][pFaction]][fName], name, message);
    }
    else
    {
        format(string, sizeof(string), "%s: %s", name, message);
    }
    
    return string;
}

Парсинг команд
Код:
ParseCommand(cmdtext[], cmd[], params[], maxParamsLen)
{
    new pos = strfind(cmdtext, " ");
    if(pos == -1)
    {
        strcpy(cmd, cmdtext, maxParamsLen);
        params[0] = '\0';
    }
    else
    {
        strmid(cmd, cmdtext, 0, pos, maxParamsLen);
        strmid(params, cmdtext, pos + 1, strlen(cmdtext), maxParamsLen);
    }
}

// Использование
new cmd[32], params[128];
ParseCommand("/give 1 1000", cmd, params, sizeof(params));
// cmd = "/give", params = "1 1000"

Поиск и замена
Код:
ReplaceString(string[], find[], replace[], maxLen = sizeof(string))
{
    new pos = strfind(string, find, true);
    if(pos != -1)
    {
        new len = strlen(find);
        new replaceLen = strlen(replace);
        
        // Удаление старой строки
        strdel(string, pos, pos + len);
        
        // Вставка новой строки
        strins(string, replace, pos, maxLen);
        
        return 1;
    }
    return 0;
}

// Замена всех вхождений
ReplaceAll(string[], find[], replace[], maxLen = sizeof(string))
{
    new count = 0;
    while(ReplaceString(string, find, replace, maxLen))
    {
        count++;
    }
    return count;
}

Разделение строки
Код:
SplitString(source[], delimiter[], result[][], maxResults, maxLen)
{
    new count = 0;
    new pos = 0;
    new len = strlen(source);
    
    while(pos < len && count < maxResults)
    {
        new nextPos = strfind(source, delimiter, false, pos);
        if(nextPos == -1)
        {
            nextPos = len;
        }
        
        strmid(result[count], source, pos, nextPos, maxLen);
        count++;
        
        pos = nextPos + strlen(delimiter);
    }
    
    return count;
}

// Использование
new parts[10][32];
new count = SplitString("apple,banana,orange", ",", parts, sizeof(parts), sizeof(parts[]));
// parts[0] = "apple", parts[1] = "banana", parts[2] = "orange"

Обрезка пробелов
Код:
TrimLeft(string[])
{
    new len = strlen(string);
    new start = 0;
    
    while(start < len && string[start] == ' ')
    {
        start++;
    }
    
    if(start > 0)
    {
        strdel(string, 0, start);
    }
}

TrimRight(string[])
{
    new len = strlen(string);
    new end = len;
    
    while(end > 0 && string[end - 1] == ' ')
    {
        end--;
    }
    
    if(end < len)
    {
        strdel(string, end, len);
    }
}

Trim(string[])
{
    TrimLeft(string);
    TrimRight(string);
}

Проверка на число
Код:
IsNumeric(string[])
{
    new len = strlen(string);
    if(len == 0) return 0;
    
    for(new i = 0; i < len; i++)
    {
        if(string[i] < '0' || string[i] > '9')
        {
            if(i == 0 && string[i] == '-')
            {
                continue; // отрицательное число
            }
            return 0;
        }
    }
    return 1;
}

IsFloat(string[])
{
    new len = strlen(string);
    if(len == 0) return 0;
    
    new hasDot = 0;
    for(new i = 0; i < len; i++)
    {
        if(string[i] == '.')
        {
            if(hasDot) return 0;
            hasDot = 1;
        }
        else if(string[i] < '0' || string[i] > '9')
        {
            if(i == 0 && string[i] == '-')
            {
                continue;
            }
            return 0;
        }
    }
    return 1;
}

Экранирование строк
Код:
EscapeString(source[], dest[], maxLen = sizeof(dest))
{
    new len = strlen(source);
    new destPos = 0;
    
    for(new i = 0; i < len && destPos < maxLen - 1; i++)
    {
        switch(source[i])
        {
            case '\'': 
            {
                if(destPos < maxLen - 2)
                {
                    dest[destPos++] = '\\';
                    dest[destPos++] = '\'';
                }
            }
            case '"':
            {
                if(destPos < maxLen - 2)
                {
                    dest[destPos++] = '\\';
                    dest[destPos++] = '"';
                }
            }
            case '\\':
            {
                if(destPos < maxLen - 2)
                {
                    dest[destPos++] = '\\';
                    dest[destPos++] = '\\';
                }
            }
            default:
            {
                dest[destPos++] = source[i];
            }
        }
    }
    
    dest[destPos] = '\0';
    return destPos;
}

Форматирование чисел
Код:
FormatNumber(number, output[], maxLen = sizeof(output))
{
    new string[32];
    valstr(string, number);
    
    new len = strlen(string);
    new outputPos = 0;
    new digits = 0;
    
    // Обработка отрицательных чисел
    if(number < 0)
    {
        output[outputPos++] = '-';
        len--;
    }
    
    for(new i = 0; i < len && outputPos < maxLen - 1; i++)
    {
        output[outputPos++] = string[i + (number < 0 ? 1 : 0)];
        digits++;
        
        // Добавление разделителя каждые 3 цифры
        if(digits % 3 == 0 && i < len - 1)
        {
            output[outputPos++] = ' ';
        }
    }
    
    output[outputPos] = '\0';
    return outputPos;
}

// Использование
new formatted[32];
FormatNumber(1000000, formatted);
// formatted = "1 000 000"

Важные моменты:
- Всегда проверяйте размеры буферов
- Используйте правильные функции для задач
- Оптимизируйте частые операции
- Обрабатывайте граничные случаи

Правильная работа со строками упрощает разработку!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху