Какой тип проверки ввода можно выполнить с двоичными данными в C ++? - PullRequest
1 голос
/ 23 декабря 2010

скажем, у меня есть такая функция в C ++, которую я хочу опубликовать третьим лицам. Я хочу сделать так, чтобы пользователь знал, что произошло, если он / она вводит неверные данные и происходит сбой библиотеки.

Допустим, если это поможет, я тоже могу изменить интерфейс.

int doStuff(unsigned char *in_someData, int in_data_length);

Что можно сделать, кроме проверки входных данных для конкретного приложения (например, посмотреть, начинается ли двоичный файл с известного идентификатора и т. Д.)? Например. могу ли я сообщить пользователю, если он / она передает in_someData, который имеет только 1 байт данных, но передает 512 как in_data_length?

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

Ответы [ 3 ]

4 голосов
/ 23 декабря 2010

Невозможно проверить, имеет ли параметр in_data_length, переданный функции, правильное значение. Если бы это было возможно, параметр был бы избыточным и, следовательно, ненужным.

Но вектор из стандартной библиотеки шаблонов решает это:

int doStuff(const std::vector<unsigned char>& in_someData);

Таким образом, нет возможности "NULL-буфера" или неверного параметра длины данных.

1 голос
/ 23 декабря 2010

Если бы вы знали, сколько байтов прошло мимо in_someData, зачем вам вообще нужно in_data_length?

На самом деле, вы можете проверить только in_someData для NULL и in_data_length для положительногозначение.Затем верните код ошибки, если это необходимо.Если пользователь передал какой-то мусор вашей функции, эта проблема, очевидно, не ваша.

0 голосов
/ 23 декабря 2010

В C ++ волшебное слово, которое вы ищете, это «исключение». Это дает вам способ сообщить вызывающему абоненту, что что-то пошло не так. Вы получите код типа

int 
doStuff(unsigned char * inSomeData, int inDataLength) throws Exception {
    // do a test
    if(inDataLength == 0)
       throw new Exception("Length can't be 0");
    // only gets here if it passed the test
    // do other good stuff
    return theResult;
}

Теперь в вашем конкретном примере есть еще одна проблема, потому что в C или C ++ нет универсального способа определить, насколько длинным является массив примитивов. Это всего лишь биты, с inSomeData адресом первых бит. Строки являются особым случаем, потому что существует общее соглашение, что нулевой байт заканчивает строку, но вы не можете зависеть от этого для двоичных данных - нулевой байт - это просто нулевой байт.

Обновление

В настоящее время это подняло некоторые отрицательные отзывы, по-видимому, от людей, введенных в заблуждение комментарием о том, что спецификации исключений устарели. Как я заметил в комментарии ниже, на самом деле это не так - хотя спецификация в C ++ 11 будет устаревшей , сейчас она все еще является частью языка, поэтому, если спрашивающий не пишет путник времени в 2014 году предложение throws по-прежнему является правильным способом написания его на C ++.

Также обратите внимание, что первоначальный спрашивающий говорит: «Я хочу сделать так, чтобы пользователь знал, что произошло, если он / она введет [sic] недействительные данные и произойдет сбой библиотеки». Таким образом, вопрос заключается не только в том, что я могу сделать, чтобы проверить входные данные (ответ: не так много, если вы не знаете больше о входных данных, чем было заявлено), а в том, как мне сказать вызывающему абоненту, что он облажался? И ответом на это является «использовать механизм исключений», который, безусловно, не устарел.

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