Почему параметр n в snprintf игнорируется?
Я обнаружил, что параметр n
функции snprintf()
игнорируется в моем коде.
char asdf[10];
Serial1.println(snprintf(asdf, 2, "hello"));
Это печатает 5, хотя я ожидал, что будет напечатано 2. Что происходит?
@Westin, 👍8
Обсуждение3 ответа
Лучший ответ:
snprintf() не будет записывать больше, чем <size> (2d аргумент snprintf) в ваш буфер, но он считает (и отбрасывает лишние) символы, которые он бы написал, если бы было достаточно места, и это число, которое он возвращает. Да, это может сбить с толку!
Смотрите ссылку на snprintf().
Это было бы полезно, потому что вы могли бы snprintf
обратиться к очень маленькому буферу, записать возвращаемое число, затем malloc
буфер соответствующего размера и сделать это снова. Таким образом, вы знаете, сколько байт нужно выделить., @Nick Gammon
@NickGammon: Или вы можете snprintf
вообще не использовать буфер (нулевой указатель назначения явно описан как действительный аргумент для случая destlength==0) при измерении длины., @supercat
Действительно. Это также делается в процедурах вывода текста Windows, чтобы измерить, сколько места будет занимать текст определенного шрифта, без его фактического рисования., @Nick Gammon
Тестовый скетч для Arduino Uno:
char buffer[10];
void setup() {
Serial.begin(9600);
int n = snprintf(buffer, 2, "hello");
Serial.println(n);
Serial.println(buffer);
}
void loop() {
}
Как написал @JRobert, ключевое слово «хотел бы». Насколько мне известно, только snprintf и vsnprintf возвращает число, которое "будет иметь".
Я думаю, причина в том, чтобы определить, была ли строка усечена. Предположим, что параметр «размер» равен 25, а строка формата очень длинная, тогда возвращаемое значение можно проверить на соответствие 25. Если возвращаемое значение было 26 («должное» количество байтов), то строка была усечена.< бр> Эту информацию невозможно было получить, поскольку номер «хотел бы иметь» был недоступен.
Для завершения, справочная страница для fprintf
утверждает:
Функция snprintf() должна быть эквивалентна sprintf(), с добавление аргумента n, который указывает размер буфера упоминается с. Если n равно нулю, ничего не записывается и s может быть нулевым указателем. В противном случае выходные байты после n-1-го должны быть отбрасывается вместо записи в массив, и нулевой байт записывается в конце байтов, фактически записанных в массив.
и, что более актуально:
После успешного завершения функция snprintf() вернет количество байтов, которые были бы записаны в s, если бы n было достаточно большой, исключая завершающий нулевой байт.
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
- Как преобразовать строку в массив байтов
- Как отправить строку на мастер с помощью i2c
- Создание форматированной строки (включая числа с плавающей запятой) в Arduino-совместимом C++
Содержит ли переменная asdf «привет» или «h»? Если он содержит «h», то параметр не был проигнорирован., @Nick Gammon