из String в char* array

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

можно и через for, просто strcat вызывается много раз

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Да можно вообще без них так-то.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

да можно и не очищать, вместе с *ptr = 0; канет в лету , но по мне так лучше очистить

arduinec
Offline
Зарегистрирован: 01.09.2015

Valera19701 пишет:
strcat тормознутая

Повеселил! Ну ооочень тормознутая :)
Вывод на графический дисплей одной строки занимает больше времени чем все strcat'ы в функции utf8rus().

Вот без strcat (на Ардуине не проверял):

#define maxString 21
char target[maxString + 1] = "";

char *utf8rus(char *source)
{
  int i,j,k;
  unsigned char n;

  k = strlen(source); i = j = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB8; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
          break;
        }
      }
    }

    target[j] = n; j++; if (j >= maxString) break;
  }

  target[j] = 0; return target;
}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valera19701 пишет:
strcat тормознутая
Жесть - это отожжённая холоднокатная сталь такая.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП пишет:

Valera19701 пишет:
strcat тормознутая
Жесть - это отожжённая холоднокатная сталь такая.

не жесть, а 4 строки по 21 символу на 1мс, относительно моего

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

arduinec пишет:

 target[j] = 0; return target;

:)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valera19701 пишет:

ЕвгенийП пишет:

Valera19701 пишет:
strcat тормознутая
Жесть - это отожжённая холоднокатная сталь такая.

не жесть, а 4 строки по 21 символу на 1мс, относительно моего

Так я ж и говорю.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП, где-то вы ссылку давали на скетч проверки кол-ва памяти, найти не могу, поделитесь

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вот здесь есть библиотека memoryExplorer. Она не только количество показывает, но и фрагемнтацию на куски. Там в посте полно примеров её использования. Кстати в том посте подробно разбирается Ваша ошибка из этого поста - возврат указателя на уничтожаемую переменную.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

Спасибо, а пока здесь какие есть ошибки

char* target = new char(1);
char* utf8rus(char *source) {
  uint8_t i = 0;
  unsigned char n;
  uint8_t k = strlen(source);
  if (*target) {
    delete[] target; *target = 0x00;
    char* target = new char(k + 1);
  }
  char* ptr = target;
  while (i < k) {
    n = source[i]; i++;
    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
            n = source[i]; i++;
            if (n == 0x81) {
              n = 0xA8;
              break;
            }
            if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
            break;
          }
        case 0xD1: {
            n = source[i]; i++;
            if (n == 0x91) {
              n = 0xB8;
              break;
            }
            if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
            break;
          }
      }
    }
    *ptr++ = n;
  }
  *ptr = 0x00;
  return target;
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы почитали бы тот пост. Я ведь не для того его писал, чтобы по сто раз повторять одно и тоже. Там ВСЁ написано.

Ну, например,  переменная target из строки №8 (даже если бы Вы там правильно запросили память) не имеет никакого отношения к перемнной target  из строки №10. Это РАЗНЫЕ переменные! В строке №10 будет использована переменная из строки №1. А запрошенная Вами в строке 8 память будет просто потеряна. И, кстати, в строке №8 Вы опять запрашиваете 1 байт, а вовсе не  k+1 как Вы думаете.

Прочитайте все три этюда про память, внимательно, разбирая примеры. Потом перепишите программу. Именно в таком порядке: сначала внимательно прочитайте. а потом к программе, т.к. Ваше "а пока здесь" не работает.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП, спасибо, бегло прочел, и понял, из-за фрагментации нужно использовать только статический массив, на досуге вдумчиво прочитаю

arduinec
Offline
Зарегистрирован: 01.09.2015

Valera19701 пишет:
arduinec пишет:

 target[j] = 0; return target;

:)

Valera19701 похоже не понял: target[j] = 0 завершает строку нулём (так надо для работы со строками), а return target возвращает всю строку.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

тогда не так, а так target[j + 1] = '\0'

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Valera19701 пишет:

тогда не так, а так target[j + 1] = '\0'

там есть инкремент выше

31    target[j] = n; j++; if (j >= maxString) break;

 

arduinec
Offline
Зарегистрирован: 01.09.2015

Valera19701 пишет:

тогда не так, а так target[j + 1] = '\0'

Неправильно так как target[j+1] может выйти за границы массива, '\0' = 0.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

xDriver, да точно, инкремент на выходе из while будет выше, просчитался

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

arduinec пишет:

Неправильно так как target[j+1] может выйти за границы массива, '\0' = 0.

Поскольку массив состоит из одного символа (см стр. №1) , она не "может выйти", а "не может не выйти".

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ЕвгенийП пишет:

 массив состоит из одного символа 

И тому уже free сказали в седьмой строке. Правда, неправильно.

arduinec
Offline
Зарегистрирован: 01.09.2015

ЕвгенийП пишет:

arduinec пишет:

Неправильно так как target[j+1] может выйти за границы массива, '\0' = 0.

Поскольку массив состоит из одного символа (см стр. №1) , она не "может выйти", а "не может не выйти".

Это касается моего кода в посте #54 - в нём может выйти.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А, сорри, а я последний код топика (#61) обcуждаю - недоразумение вышло :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

до этого я б даже с жесточайшего збадуна  не додумалса бы

06   if (*target) {
07     delete[] target; *target = 0x00;
08     char* target = new char(k + 1);
09   }

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Дык, я ж говорю ТС: "почитай этюды про память", а он всё "потом, а сейчас скажи, что не так" :)))

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

DetSimen пишет:

до этого я б даже с жесточайшего збадуна  не додумалса бы

придете вы со схемой , где в source n-channel mosfet нагрузка стоит :)

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

arduinec, вот так я думаю будет лучше или нет?

#define str_utf_len 90
char target[str_utf_len + 1];
char* utf8rus(char *source) {
  uint8_t i = 0, j = 0;
  unsigned char n;
  uint8_t k = strlen(source);
  for (uint8_t p = 0; p < str_utf_len + 1; p++) {
    target[p] = '\0';
  }
  while (i < k ) {
    n = source[i]; i++;
    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
            n = source[i]; i++;
            if (n == 0x81) {
              n = 0xA8;
              break;
            }
            if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
            break;
          }
        case 0xD1: {
            n = source[i]; i++;
            if (n == 0x91) {
              n = 0xB8;
              break;
            }
            if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
            break;
          }
      }
    }
    target[j] = n; j++; if (j >= str_utf_len) break;
  }
  //target[j] = '\0'; //не нужно, так как массив очищаем
  return target;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

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

b707
Offline
Зарегистрирован: 26.05.2017

код в #76 - в строке 7 опять выход ха границу массива.  И к чему вообще этот кусок? - зачем весь массив забивать нулями ? не проще было бы оставить однократное добавление нуля в конце?

поправка - выхода за границу вроде нет, единицу не увидел. Но вопрос "зачем это" остался

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Valera19701 пишет:

DetSimen пишет:

до этого я б даже с жесточайшего збадуна  не додумалса бы

придете вы со схемой , где в source n-channel mosfet нагрузка стоит :)

боюсь, до этого я тоже не додумаюсь. 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Валера, вы бы для начала сформулировали, чего пытаетесь добиться. Иначе всё по кругу ходите.

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

sadman41, хотел добиться универсальности, и скорости, и чтобы не смотреть на размер строки

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Не надо общими словами - "мир во всём мире и чтобы не было войны". 

Надо из входного массива ... с типом ..., содержащего строку utf-8 произвести трансформацию в строку ASCII копированием/заменой/... в выходной массив ... с типом ... и т.п.

Вы сейчас пишете что-то для массива в RAM, потом ему в реальном коде подсунете указатель на ROM, получите треш и угар. Будете потом опять башку чесать - а что же тут не то, работало ж.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

b707, я не знаю как у програмистов по феншую, очищать массив или добавляать конец строки?

я не програмист по професии, а электронщик, а это просто хобби

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

sadman41, мне нужно такой же функционал как в прототипе со String, чтоб не смотреть на размер входящей строки, а уже из ром или рам там я уже разрулю

sadman41
Онлайн
Зарегистрирован: 19.10.2016

String и так написан для того, чтобы не смотреть "на размер". Сомневаюсь, что вы напишете что-то более подходящее.

b707
Offline
Зарегистрирован: 26.05.2017

Valera19701 пишет:

как у програмистов по феншую, очищать массив или добивать конец строки?

от контекста зависит. В данном случае очищать незачем

Цитата:

я не програмист по професии, а электронщик, а это просто хобби

если вы пытаетесь программировать - значит в этот момент своей жизни вы программист. А по профессии мы тут все или почти все - не программисты.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А зачем target забивать нулями ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valera19701 пишет:

из ром или рам там я уже разрулю

:-)))))

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП, вот из ром, что-то опять не так

#define lang_buff 50
char buffers[lang_buff] = "";
char *lang(uint8_t num, uint8_t language) {
  switch (language) {
    case 0:
      strcpy_P(buffers, (char*)pgm_read_word(&(rus[num])));
      strcpy(buffers, utf8rus(buffers));
      break;
    case 1:
      strcpy_P(buffers, (char*)pgm_read_word(&(eng[num])));
      break;
  }
  return buffers;
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так ото ж!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valera19701 пишет:

sadman41, мне нужно такой же функционал как в прототипе со String

А чем не устраивает String?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ну колитесь что не так?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

brokly пишет:

А зачем target забивать нулями ?

Фильм один видел как-то по Культуре. Не целиком, а фрагмент. Названия не помню абсолютно. Главный герой - изобретатель деревенский. В пекарне сделал перемешиватель теста из велосипеда, ещё чего-то... И у него был такой "подручный" - дед-пенсионер. Дал изобретатель задание ему - на досочках разные картинки вырезать, чтобы на пряниках отпечатывать.

Сцена: главный герой на результат работы смотрит и этого деда спрашивает - "а чего этот, на лошади, змеюку палкой тыкает?" Дед ему в ответ - "а чтобы неповадно было!"

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП пишет:

А чем не устраивает String?

Потихоньку переползаю с ардуино вайринга, на атмел студию

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Сцена: главный герой на результат работы смотрит и этого деда спрашивает - "а чего этот, на лошади, змеюку палкой тыкает?" Дед ему в ответ - "а чтобы неповадно было!"

Свят Георгий во бою...
На белóм сидит коню
Держит в руце копие
Колет змия в жопие

b707
Offline
Зарегистрирован: 26.05.2017

Valera19701 пишет:

Потихоньку переползаю с ардуино вайринга, на атмел студию

меня всегда поражает - почему "уйти от ардуино" в первую очередь тянет тех, кто вовсе "не программист" ? Почему от Евгения или Sadman41 или dimax-а вы не слышите жалоб на то, что вайринг не дает им выразить себя? :)

Вы может думаете, что глюки ваших программ - от "кривого вайринга"? :) - вы ошибаетесь.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

b707, я хочу просто научиться прорамировать напрямую , например через регистры, вайринг это делает за меня, а не выражать себя, от меня вы хоть раз слышали слова о кривом вайринге?

b707
Offline
Зарегистрирован: 26.05.2017

Валера, прошу прощения за высказывания... но мне кажется. вам надо в первую очередь базовые понятия Си подтянуть - ссылки. массивы, строки, битовые операции... а регистры - это тупая конкретика, ее освоить недолго, когда база есть.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Valera19701 пишет:

ЕвгенийП пишет:

А чем не устраивает String?

Потихоньку переползаю с ардуино вайринга, на атмел студию

Сейчас я Вам расскажу страшный секрет переползания, только не палите, что это я Вам сказал.

1. Берёте из поставки Adruino IDE два файла: WString.h и WString.cpp;
2. Копируете их в свой проект в студии;
3. Пользуетесь String в студии сколько душе угодно.

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП, ответить с сарказмом или без?