Объявления

Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

H3API by RoseKavalier

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: H3API by RoseKavalier

Сообщение AlexSpl » 28 май 2020, 19:52

Если мы хотим заменить в строке подстроку большей по длине строкой, то чтобы не заморачиваться с выделением памяти, нужно делать так (а именно, использовать заведомо большой буфер):

Код: Выделить всё
#include <stdlib.h>
#include <stdio.h>

int main(int argc, const char * argv[])
{
    const char *s = "This is a test";
    int i = 0;
    int new_len = 0;

    // We don't know what the final size of the string will be, so
    // let's make one that's generally large enough. Can do more
    // elaborate things here if you want a really robust solution.
    char new_string[256] = {0};

    // For each character in the string:
    for (i=0; s[i] != '\0'; ++i)
    {
        if (s[i] == 't' && s[i+1] == 'e')
        {
            // If we find "te", add "gho".
            new_string[new_len++] = 'g';
            new_string[new_len++] = 'h';
            new_string[new_len++] = 'o';

            // ... and skip one character to ignore both the 't' and the 'e'.
            ++i;
        }
        else
        {
            // Otherwise just add the same character.
            new_string[new_len++] = s[i];
        }
    }

    // Add the null terminator at the end of our new string.
    new_string[new_len] = '\0';

    // Output the new string.
    printf("%s\n", new_string);
    system("pause");
}
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: H3API by RoseKavalier

Сообщение Ben80 » 28 май 2020, 20:08

Мне кажется, это как раз не самое лучшее решение, поскольку в противоположность заявленной цели, как раз существует теоретическая возможность выделить недостаточный объем памяти (а память вы безусловно все-таки выделяете - 256 байт).

Если речь идет об изменении чисел, то вполне достаточно взять размер оригинальной строки + скажем 10 байт (не будут же в самом деле числа до и после отличаться более чем в 10 млрд. раз !).

***

Хотя согласен, что проще сразу выделить память статически, чем делать это динамически.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: H3API by RoseKavalier

Сообщение AlexSpl » 28 май 2020, 20:19

Ben80, для рассматриваемой проблемы да. Нам нужно заменить 10 на другой процент. И strstr() отлично справляется с этой задачей, т.к. strstr(myString, "mySubString") - myString - это индекс первого вхождения подстроки в строку. Но без буфера, если не считать, насколько увеличился/уменьшился размер строки, замену подстроки просто так не произведёшь.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: H3API by RoseKavalier

Сообщение Ben80 » 28 май 2020, 20:27

Так в данном случае необязательно знать, насколько увеличился размер строки - нам же точно известно, что более в 10 млрд. раз число не увеличится.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: H3API by RoseKavalier

Сообщение AlexSpl » 28 май 2020, 20:31

Дело в том, что char* - это указатель, и когда мы объявляем char* myString = "myString", выделяется память под строку (в данном случае 9 байт, причём последний под '\0'). Так что я бы решал данную проблему через буфер.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: H3API by RoseKavalier

Сообщение Ben80 » 28 май 2020, 20:35

Ну так я уже написал, что вы выделяете память статически, что достаточно удобно. А можно выделить динамически, через new, копируя непосредственно в приемник. Естественно в этом случае '\0' тоже должно быть использовано.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: H3API by RoseKavalier

Сообщение AlexSpl » 28 май 2020, 20:37

Вы не можете, в общем случае, выделить память динамически, поскольку не знаете, на сколько байт увеличится/уменьшится Ваша строка после всех замен.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: H3API by RoseKavalier

Сообщение Ben80 » 28 май 2020, 20:41

В данном случае я просто беру размер оригинальной строки и прибавляю 10 байт - этого размера будет достаточно. И его можно выделить динамически.
Если неизвестно, каков будет характер замен, то так делать нельзя, а если известно, что у нас изменится одно число, то можно.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: H3API by RoseKavalier

Сообщение AlexSpl » 28 май 2020, 20:47

Твои 10 байт и есть буфер :smile2:

Если по всей строгости, то нужно реаллокейтить память после всякого обнаружения подстроки в строке на величину их различия.

Конкретно в задаче as239 нам нужны три конкатенации: строки до появления нужной подстроки, строки, которую мы меняем, и остатка строки без подстроки, которую мы заменили.

Со строками char* в С всегда были проблемы, поэтому и придумали String.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: H3API by RoseKavalier

Сообщение as239 » 29 май 2020, 09:25

Added operator[] at "H3ColumnTextFile":
Код: Выделить всё
// * text file with a single column of text
struct H3ColumnTextFile : public H3BinaryItem
{
protected:
   // * +1C list of rows holding text, single column
   H3Vector<LPCSTR> text;
   // * +2C
   LPCSTR buffer;
   // the buffer size is not stored for this format
public:
   LPCSTR GetText(INT32 row) const { return text.m_first[row - 1]; } // using the index from TxtEdit
   static H3ColumnTextFile* Load(LPCSTR name) { return THISCALL_1(H3ColumnTextFile*, 0x55BDA0, name); }
   VOID UnLoad() { THISCALL_1(VOID, vTable->dereference, this); }
   LPCSTR & H3ColumnTextFile::operator[](UINT row)
   {
      return *text[row];
   }
};


But having crash trying to replace string:
Код: Выделить всё
H3ColumnTextFile& __stdcall _HH_LoadHeroSpecTxt(HiHook* h, LPCSTR filename)
{
   H3ColumnTextFile& heroSpecText = THISCALL_1(H3ColumnTextFile&, h->GetDefaultFunc(), filename);
      for (int i = 0; i < 150; i++)
      {
         heroSpecText[i] = "test";
   
      }

   return heroSpecText;
}

   _PI->WriteHiHook(0x4D7415, CALL_, THISCALL_, _HH_LoadHeroSpecTxt);
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

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

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