Помогите разобраться, что за глюк co string.length()

MaksVV
Offline
Зарегистрирован: 06.08.2015

Да, это верно. Я сделал перекодировку по этому принципу в сообщении #34.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

MaksVV пишет:
Да, это верно. Я сделал перекодировку по этому принципу в сообщении #34.

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

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

Penni пишет:

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

забавно... спасибо за инфу.

Честно говоря, всегда был уверен, что char - это unsigned byte

MaksVV
Offline
Зарегистрирован: 06.08.2015

Клапауций 112 пишет:
шо ты там мог делать, если до сих пор не научился текстовые файлы в нужной кодировке сохранять.

вообщето код рабочий. А твой вариант с кодировками плохо катит.  Открой предоставленный тобой скетч, хотябы один символ затронь и все слетает, опять в блокнот лезть?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

MaksVV пишет:

опять в блокнот лезть?

нет - идти найух, если тебе ни один из предложенных вариантов не подходит.

*как по мне, вместо устраивать программный цирк с конями на стороне контроллера, проще дать контроллеру текст с которым он будет работать корректно.

MaksVV
Offline
Зарегистрирован: 06.08.2015

ты главное не кипятись, варианты это хорошо. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Penni пишет:

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

1. Проблема в том, что длина символа в utf-8 может достигать 6 байт. Конечно - да, все символы кириллицы имеют по 2 байта, но вдруг попадется какой-то дргуой символ? Правильная программа должна корректно обрабатывать ситуацию неверных входных данных, а Ваш вариант даже на верных (т.е. корректных символах utf-8) будет врать.

2. Я не специалист по Си, но что-то мне помнится, что в стандарте не оговорено, char - это знаковый или беззнаковый тип. Поэтому проверка на отрицательность будет работать не на любом компиляторе. Для надежного кода, опять же, нужно не сравнение с 0, а проверка старшено бита.

ПРактика показывает, что когда в коде подобные "ненадежности" встречаются 1-2 раза, еще удается добиться более или менее надежной работы. Но когда фрагмсенты кода гуляют из проекта в проект и суммарное количество "ненадежностей" достигает 5-7 - проект "валится" и тогда уже оказывается проще написать с нуля, чем выискивать источник подобных ошибок.

Так что уж лучше сразу писать надежно (т.е. наверняка и не надеясь на умолчания и на то, что программа всегда будет иметь дело с корректными данными).

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

andriano пишет:
что-то мне помнится, что в стандарте не оговорено, char - это знаковый или беззнаковый тип. 

"It is implementation-defined whether a char object can hold negative values. ... In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined" (ISO/IEC 14882:2014(E), chapt. 3.9.1(1)? page 71)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

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

"It is implementation-defined whether a char object can hold negative values. ... In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined" (ISO/IEC 14882:2014(E), chapt. 3.9.1(1)? page 71)

ок. это всё ясно, что ничего не определено однозначно и что-то от чего-то зависит...

а, как так может быть? как бы уже договорились, что шлётся один байт - не суть важно в каком типо-виде:

Returns

the first byte of incoming serial data available (or -1 if no data is available) - int

т.е. если что-то пришло, то это у нас тип чар, а если не пришло, то это тип int ?

а, пример, вообще, принимает в непонятно чём байты символов - типо чар, но int.

int incomingByte = 0;	// for incoming serial data

void setup() {
	Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps
}

void loop() {

	// send data only when you receive data:
	if (Serial.available() > 0) {
		// read the incoming byte:
		incomingByte = Serial.read();

		// say what you got:
		Serial.print("I received: ");
		Serial.println(incomingByte, DEC);
	}
}

https://www.arduino.cc/en/Serial/Read

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Тип того, что приходит, определяется объектом Serial. А операция присваивания преобразует это "что-то" к типу int (что, вообще говоря, совершенно излишне - но уж так написал автор этого кода). При этом результат преобразования зависит от того, знаковым был исходный тип или беззнаковым. Поэтому единственный надежный способ (IMHO) - проверять бит D7.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andriano пишет:

Тип того, что приходит, определяется объектом Serial. А операция присваивания преобразует это "что-то" к типу int (что, вообще говоря, совершенно излишне - но уж так написал автор этого кода). При этом результат преобразования зависит от того, знаковым был исходный тип или беззнаковым. Поэтому единственный надежный способ (IMHO) - проверять бит D7.

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

    unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
    unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];

получается, что нет смысла париться, в каком формате(знаковом или нет) отправляем или получаем - главное, что бы это занимало диапазон одного байта.

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

*у меня вот это вызывает диссонанс: http://arduino.ru/Reference/Char

Тип char знаковый тип, т.е. число (код) хранящийся в памяти может принимать значения от -128 до 127. Если необходим беззнаковая однобайтовая переменная, используйте тип byte.

в то время, как таблица символов ASCII - беззнаковая.

в то время, как Терминал для DigiUSB со стороны компа отправляет и принимает символы в диапазоне -128 до 127, а со стороны контроллера в диапазоне 0-255. О_О

 

 

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

"Тип char знаковый.... "

Не обязательно.  Стандарт никак не определяет размер и знаковость типа char, это оставлено на усмотрение писателей канпиляторов (зависит от реализации).  В GCC, да, реализовали так, что он знаковый

Тип char может хранить значения в диапазоне от -128 до +127 (дополнительный код, где информацию о знаке числа несет старший бит D7). Тип unsigned char может принимать значения от 0 до 255. Некоторые компиляторы могут использовать тип byte вместо типа unsigned char.

хотя, по большому счету, код сивмола, по здравому смыслу даже, знаковым быть не должен, это же просто индекс в таблице ASCII изначально был. 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

DetSimen пишет:

хотя, по большому счету, код сивмола, по здравому смыслу даже, знаковым быть не должен, это же просто индекс в таблице ASCII изначально был. 

по большому счёту - не наблюдаю я отрицательных костяшек. О_О

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017
char ch = 193;
// или
char ch = -63;

lcd.print(ch); // печатается 'ш'

как из этого можно понять - знаковый тип чар или беззнаковый?

193 приводится к знаковому типу?

или

-63 приводится к беззнаковому?

О_О

andycat
Offline
Зарегистрирован: 07.09.2017

Клапауций 112 пишет:

char ch = 193;
// или
char ch = -63;

lcd.print(ch); // печатается 'ш'

как из этого можно понять - знаковый тип чар или беззнаковый?

193 приводится к знаковому типу?

или

-63 приводится к беззнаковому?

О_О

Приводиться где? lcd.print(ch) - печатает байт ch

и ничего нигде не приводиться, опять же выдержака с этого же сайта

Тип char знаковый тип, т.е. число (код) хранящийся в памяти может принимать значения от -128 до 127. Если необходим беззнаковая однобайтовая переменная, используйте тип byte.

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

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

Приводиться где? lcd.print(ch) - печатает байт ch

и ничего нигде не приводиться, опять же выдержака с этого же сайта

Тип char знаковый тип, т.е. число (код) хранящийся в памяти может принимать значения от -128 до 127. Если необходим беззнаковая однобайтовая переменная, используйте тип byte.

выдержками из ссайтов тут мало кому что докажешь: утверждение, что может принимать значения от -128 до 127 так же верны, как и что может принимать от -128+n до 127+n, где n - любое целое цисло.

andycat пишет:

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

чего с чем арифметических операций, если у нас не число, а диапазон возможных значений длиной в 1 байт?

andycat
Offline
Зарегистрирован: 07.09.2017

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

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

например

if (b<0)

никогда не сработает если переменная b типа byte или word

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

например

if (b<0)

никогда не сработает если переменная b типа byte или word

да? и, чему в твоём "никогда" равен ноль(0) ? 

вот, например в чаре ноль(0) может быть равен -128 или 0(ноль). О_О

andycat
Offline
Зарегистрирован: 07.09.2017

Клапауций 112 пишет:

andycat пишет:

например

if (b<0)

никогда не сработает если переменная b типа byte или word

да? и, чему в твоём "никогда" равен ноль(0) ? 

вот, например в чаре ноль(0) может быть равен -128 или 0(ноль). О_О

ноль он и в Африке ноль :) и в char и в byte

мне кажеться мы на разном языке разговариваем и я вопроса нифига не понял.

а условие if (b<0) никогда не будит истиной если тип переменной byte

 

andycat
Offline
Зарегистрирован: 07.09.2017

пожалуйста пример, LED2 не горит, можете сами проверить.

#define LED1 7
#define LED2 8

char b = -67;

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW);
  pinMode(LED1, OUTPUT); digitalWrite(LED1, LOW);
  pinMode(LED2, OUTPUT); digitalWrite(LED2, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (b < 0) {
    digitalWrite(LED1, HIGH);
  }
  byte c = b;
  if (c < 0) {
    digitalWrite(LED2, HIGH);
  }
}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

ноль он и в Африке ноль :) и в char и в byte

нет в char ноль может быть равен нулю или -128 -сказано же выше, что всё не так однозначно:

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

"It is implementation-defined whether a char object can hold negative values. ... In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined" (ISO/IEC 14882:2014(E), chapt. 3.9.1(1)? page 71)

andycat пишет:

а условие if (b<0) никогда не будит истиной если тип переменной byte

при чём тут byte вообще, если мы о char говорим?

andycat
Offline
Зарегистрирован: 07.09.2017

началось все вот с этого:

1 char ch = 193;
2 // или
3 char ch = -63;
4  
5 lcd.print(ch); // печатается 'ш'

как из этого можно понять - знаковый тип чар или беззнаковый?

 

я просто пытаюсь объяснить что с точки зрения lcd.print абсолютно без разницы знаковый он или беззнаковый

пожалуйста пример:

#define LED1 7
#define LED2 8

char b = -67;

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW);
  pinMode(LED1, OUTPUT); digitalWrite(LED1, LOW);
  pinMode(LED2, OUTPUT); digitalWrite(LED2, LOW);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (b < 0) {
    digitalWrite(LED1, HIGH);
  }
  byte c = b;
  if (c < 0) {
    digitalWrite(LED2, HIGH);
  }
  b = 193;
  Serial.println(b,BIN);
  b = -63;
  Serial.println(b,BIN);
  delay(1000);
}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

шо это за читерство?

тип байт начинается с нуля

тип чар начинается с -128

значит и сравнивать нужно с 0 и -128 соответсвенно. О_О

andycat
Offline
Зарегистрирован: 07.09.2017

Клапауций 112 пишет:

шо это за читерство?

тип байт начинается с нуля

тип чар начинается с -128

значит и сравнивать нужно с 0 и -128 соответсвенно. О_О

сложно с вами :(

я просто ответил на вопрос считать char знаковым или беззнаковым при отправке куда либо - ответ: без разницы.

вы мне хотите доказать что если я использую char то я его должен сравнивать с -128  а не с нулем? или что?

не согласен категорически.

впрчем можете не отвечать - мне пофиг, у меня программы работают так как я и запрограммировал - надоело флудить.

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

вы мне хотите доказать что если я использую char то я его должен сравнивать с -128  а не с нулем? или что?

не согласен категорически.

а, на что ты согласен? - зачем ты чар сравниваешь с байтом и пытаешься мне доказать, что что-то там верно, потому, что сериал принт печатает чар как байт - ясен пень, как байт:

    unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
    unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];

цитата из файла HardwareSerial.h

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

andycat
Offline
Зарегистрирован: 07.09.2017

смысл в дуине в знаковом char в том же как и в остальных знаковых типах, например int или long.

программист с умом должен выбирать тип переменных в зависимости от задачи.

я например практически всегда использую беззнаковые типы byte и word - просто привычка с ассемблера.

 

буквари на всякий случай:

https://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D0%B0...

https://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8...

 

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

andycat, Вы еще не заметили, что просто кормите тролля?

andycat
Offline
Зарегистрирован: 07.09.2017

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

andycat, Вы еще не заметили, что просто кормите тролля?

 

отключаюсь :)

спасибо за совет

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

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

andycat, Вы еще не заметили, что просто кормите тролля?

тут ещё нужно разобраться, кто тролль, а кого покусал Капитан Очевидность.

...сижу себе, никого не трогаю, размышляю вслух - внезапно: байт не может быть меньше нуля.

здрасте, жопа, новый год!

andycat
Offline
Зарегистрирован: 07.09.2017

не выдержал :) пишу последний раз сюда:

да, любое двоичное число всегда положительное :)

а то что мы пишем на языках высокого уровня это все происки врагов (компилятора).

ссылки на книжки выше если что.

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

не выдержал :) пишу последний раз сюда:

да, любое двоичное число всегда положительное :)

а, ноль - это двоичное или одиничное число?

чиста, в последний раз хотел спросить... О_О

Клапаyций 112
Клапаyций 112 аватар
Offline
Зарегистрирован: 13.10.2017

 

andycat пишет:

не выдержал :) пишу последний раз сюда:

да, любое двоичное число всегда положительное :)

а, ноль - это двоичное или одиничное число?

чиста, в последний раз хотел спросить... О_О

 

Alexander
Offline
Зарегистрирован: 25.04.2010

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

 

Logik
Offline
Зарегистрирован: 05.08.2014

О какой оборот! просто мыльная опера ))) Ждем разборок лже "не Клапауций" vs не "лже не Клапауций" )))

А может этот "не Клапауций" очередная реинкарнация Клапауцийя? Но попкорном запасусь.

По теме - интерпретация всех 256 состояний регистра 8-битного МК: знаковое, беззнаковое, целое или символ - чистейшая условность. Общепринятые типы - просто широко известные (написал бы всем известные, но судя по теме не всем) условности облегчающие взвимопонимание между людьми и компиляторами. Я к примеру считаю что первые 4 бита это мантиса, затем 1 бит это знак порядка а остальные 3 - порядок. Кто поспорит с этим?

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

Logik пишет:
Кто поспорит с этим?
Операция сложения.

Logik
Offline
Зарегистрирован: 05.08.2014

Перегружена. Работает корректно. Что ваша операция сложения думает по поводу сложения  'a' и 'b'?

andycat
Offline
Зарегистрирован: 07.09.2017

Заканчивайте спорить)
Учебников по двоичной арифметике много.
Те кто не понимают пусть попробуют на ассемблере программировать.
Если все равно не поймут - думаю нам всем стоит остаться при своём мнении.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. Ветку в данной теме про знаковый/беззнаковый поднял я. С единственной целью - указать, что сравнение на "<0" для определения символов кириллицы некорректно и следует его заменить на проверку старшего бита (это - для байта, для произвольного целого - бита D7). Все.

2. Специально для Клапы: знаковый или беззнаковый байты ниоткуда не начинаются. 0 соответствует 0, -128 соответствует 128, а -1 соответствует 255. Но -128 нигде не соответствует 0.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Alexander пишет:

Уж не знаю кому понадобилось косить под Клапауция и хамить от его имени. 
Видимо пострадалец какой-то, затаивший обидку и печаль.

Logik пишет:

А может этот "не Клапауций" очередная реинкарнация Клапауцийя? Но попкорном запасусь.

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

логично же, да?, Логик.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andriano пишет:

2. Специально для Клапы: знаковый или беззнаковый байты ниоткуда не начинаются. 0 соответствует 0, -128 соответствует 128, а -1 соответствует 255. Но -128 нигде не соответствует 0.

а, я что выше говорил?:

Клапауций 112 пишет:

получается, что нет смысла париться, в каком формате(знаковом или нет) отправляем или получаем - главное, что бы это занимало диапазон одного байта.

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

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

я например практически всегда использую беззнаковые типы byte и word - просто привычка с ассемблера.

*ну, и к чему это сомнительное утверждение личного характера? что бы народ ломал себе голову над словоблудием "практически всегда"? - чем оно отличается от "всегда"?

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

при поверхностном взгляде - всё корректно:

// это происходит на стороне компьютера
char send_usb;      // символ отправляемый в USB.
char receive_usb;   // символ полученный из USB.
usb_control_msg(devHandle, (0x01 << 5) | 0x80, 0x01, 0, 0, &receive_usb, 1, 1000);
usb_control_msg(devHandle, (0x01 << 5), 0x09, 0, send_usb, 0, 0, 1000);

// это происходит на стороне контроллера дуино
char RX_s;
char TX_s;
RX_s = DigiUSB.read();
DigiUSB.write(TX_s);

если бы не это:

// в библиотеке DigiUSB
unsigned char buffer[RING_BUFFER_SIZE];
uchar rx_buffer[8];

посмотрел в Serial дуино - аналогично:

// в библиотеке HardwareSerial
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];

поэтому - диссонанс: что первично char или unsigned char ?

DIYMan
Offline
Зарегистрирован: 23.11.2015

Клапауций 112 пишет:

поэтому - диссонанс: что первично char или unsigned char ?

Первично - второе, всё остальное - пляски папуасов :)

andycat
Offline
Зарегистрирован: 07.09.2017

Первичны машинные коды)

А все остальное фикция.
Например вот это можно откомпилировать по разному) в библиотеке HardwareSerial
2
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
3
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

andycat пишет:

не выдержал :) пишу последний раз сюда:

О_О

andycat пишет:

Первичны машинные коды) 

А все остальное фикция.

Сроду такого не было, и опять то же самое.(с)