printf %s выдает тарабарщину

printf

Этот код:

String S0 = "";
String S1 = "1";
String S2 = "12";
String S3 = "123";
String S4 = "1234";
String S5 = "12345";
String S6 = "123456";
String S7 = "1234567";
String S8 = "12345678";
String S9 = "123456789";
String S10 = "1234567890";
String S11 = "1234567890a";
String S12 = "1234567890ab";
String S13 = "1234567890abc";
String S14 = "1234567890abcd";
String S15 = "1234567890abcde";
String S16 = "1234567890abcdef";
String S17 = "1234567890abcdefg";
String S18 = "1234567890abcdefgh";
String S19 = "1234567890abcdefghi";
String S20 = "1234567890abcdefghij";
Serial.printf("(0):%s\n", S0);
Serial.printf("(1):%s\n", S1);
Serial.printf("(2):%s\n", S2);
Serial.printf("(3):%s\n", S3);
Serial.printf("(4):%s\n", S4);
Serial.printf("(5):%s\n", S5);
Serial.printf("(6):%s\n", S6);
Serial.printf("(7):%s\n", S7);
Serial.printf("(8):%s\n", S8);
Serial.printf("(9):%s\n", S9);
Serial.printf("(10):%s\n", S10);
Serial.printf("(11):%s\n", S11);
Serial.printf("(12):%s\n", S12);
Serial.printf("(13):%s\n", S13);
Serial.printf("(14):%s\n", S14);
Serial.printf("(15):%s\n", S15);
Serial.printf("(16):%s\n", S16);
Serial.printf("(17):%s\n", S17);
Serial.printf("(18):%s\n", S18);
Serial.printf("(19):%s\n", S19);
Serial.printf("(20):%s\n", S20);

Дает такой результат:

(0):
(1):1
(2):12
(3):123
(4):1234
(5):12345
(6):123456
(7):1234567
(8):12345678
(9):123456789
(10):�H�?
(11):�^�?
(12):_�?
(13):�_�?
(14):`�?
(15):0`�?
(16):�`�?
(17):a�?
(18):@a�?
(19):pa�?
(20):�a�?

Есть какие-нибудь идеи?? PS: ОЧЕВИДНО, что для какой бы платформы он ни использовался, он работает для коротких строк, а не для более длинных строк! И на него был дан ответ в комментариях после того, как вы его закрыли! Так что, если вы не знаете ответа вместо того, чтобы закрывать, может быть, лучше оставить это для других, чтобы ответить на него ...

, 👍0

Обсуждение

Пожалуйста, предоставьте полный компилируемый код в качестве примера., @chrisl

Для какой платы вы компилируете с каким ядром? Стандартное ядро не имеет функции printf() для Serial. Ядро ESP32 так и делает. И ядро ESP8266 не принимает String в качестве параметра для него. Пожалуйста, предоставьте более подробную информацию о вашей настройке, @chrisl

Ну, я работал над тем, чтобы дать вам ответ, но ... потом кто-то закрыл его. Итак, здесь: вам нужен .c_str() в ваших вызовах. .printf() - это переменная функция, которая на самом деле не имеет доступа к какому-либо целевому типу для выполнения преобразований; она полностью зависит от вашей передачи правильных спецификаторов формата. Он просто передает байты в объект String, который не является просто const char * (указан %s). Если вам интересно, разница в поведении, которую вы видите, зависит от того, используется ли "оптимизация малых строк"., @timemage

@timemage Ценю время и усилия, которые вы потратили на объяснение этого. Я бы определенно ПРИНЯЛ и ПОДДЕРЖАЛ ваш ответ, если бы кто-то не решил закрыть его только потому, что просто не знает ответа!!! Просто добавив .c_str() в S20, я получил то, что ожидал, и ваше объяснение было ПРАВДИВЫМ и бесценным. Это также доказало, что для прояснения этого очевидного вопроса больше не требовалось никаких объяснений. МНОГИЕ СЧИТАЮТ, @AKTanara

Я предполагаю, что вопрос был закрыт из-за его качества. Хотя тем временем он был вновь открыт (возможно, из-за ответа в комментариях), так что @timemage теперь может поместить комментарий в качестве ответа., @chrisl

Похоже на оптимизацию коротких строк, когда более короткие строки хранятся непосредственно в объекте, а для более длинных строк они используются в качестве указателей. Вы должны использовать: Serial.printf("%s",Sxx.c_str());, @KIIV

@chrisl Если бы я сделал это сейчас, это была бы на 95% обличительная речь, вызванная презрением., @timemage

@AKTanara Если вы хотите, вы можете найти меня и небольшую коллекцию других в irc-сети libera.chat., @timemage

Уважаемый timemage, я найду вас там, как только узнаю, как работает эта irc-сеть libera.chat... Еще раз спасибо за хороший ответ, который вы предоставили, и я хотел бы, чтобы вы могли опубликовать свой комментарий в качестве ответа сейчас, когда тема снова открыта, чтобы я мог принять его, поскольку вы были первым, кто упомянул решение, даже когда оно было закрыто..., @AKTanara

@AKTanara, я не беспокоюсь об этом. Я помогаю людям в IRC уже очень давно, и там никогда не было системы начисления баллов. RowanP потратил время, чтобы превратить это в ответ; вероятно, будет лучше, если вы примете этот ответ, чтобы вопрос был решен в техническом смысле., @timemage


1 ответ


Лучший ответ:

4

(Ответ сообщества Wiki, собранный из комментариев)

Обратите внимание, что стандартное ядро Arduino не имеет функции Serial.printf(). Ядро ESP32 так и делает.

Вам нужен .c_str() в ваших вызовах. .printf() - это переменная функция, которая на самом деле не имеет доступа к какому-либо целевому типу для выполнения преобразований; она полностью зависит от вашей передачи правильных спецификаторов формата. Он просто передает байты в строковый объект, который не является просто const char * (указанный %s). Если вам интересно, разница в поведении, которую вы видите, зависит от того, используется ли "оптимизация малых строк".

Оптимизация коротких строк - это когда более короткие строки хранятся непосредственно в объекте, а для более длинных строк они используются в качестве указателей.

Предлагаемое решение заключается в использовании: Serial.printf("%s",Sxx.c_str());

,