Переносимым способом получения epsilon в C ++ является
#include <limits>
std::numeric_limits<double>::epsilon()
. Затем функция сравнения становится
#include <cmath>
#include <limits>
bool AreSame(double a, double b) {
return std::fabs(a - b) < std::numeric_limits<double>::epsilon();
}
Вы должны закончить строку символом \ 0. Вот почему они называются нулевыми завершенными строками.
Также целесообразно выделить 1 дополнительный символ для хранения \ 0.
Возможно, вы также захотите изучить stringstream
.
Единственное, что вы передаете функции printf (), - это указатель на первый символ вашей строки. printf () не имеет возможности узнать размер вашего массива. (Он даже не знает, является ли это фактическим массивом, поскольку указатель - это просто адрес памяти.)
printf (), и все стандартные функции строки c предполагают, что в конце ваша строка. printf (), например, будет печатать символы в памяти, начиная с символа, который вы передаете функции, до тех пор, пока он не достигнет 0.
Поэтому вы должны изменить свой код на что-то вроде этого:
char Buffer[9]; //holds the byte stream
int i=0;
if( //user input event has occured )
{
Buffer[i] = charInput;
i++;
Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result.
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
Странно, что никто не упомянул эту возможность:
char Buffer[8]; //holds the byte stream
int i = 0;
while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %.*s!\n", i, Buffer);
}
Эта нотация в строке формата printf () указывает максимальную длину строки, которая должна отображаться, и не требует нулевого завершения (хотя нулевое завершение в конечном итоге является лучшим способом - по крайней мере, когда вы покидаете этот цикл).
Цикл while
более правдоподобен, чем простой if
, и эта версия гарантирует, что вы не переполняйте конец буфера (но не оставляйте достаточно места для конечного NUL '\0'
. Если вы хотите обработать это, используйте sizeof(Buffer) - 1
, а затем добавьте NUL после цикла.
Поскольку Buffer
не инициализируется, он начинается со всех 9 значений мусора. Из наблюдаемых результатов 2, 3, 4, 5, 6, 7, 8 и 2 сразу следующие ячейки памяти (вне массива) четко обозначены 'T'
, 'T'
, 'W'
, '\0'
, '\0'
, '='
, '\0'
, '\0'
, '\0'
.
Строки уничтожают все символы до тех пор, пока не увидите символ NULL. Поэтому на каждой итерации, когда элементы массива присваиваются один за другим, буфер печатается до той части, где присутствует мусор NULL.
То есть строка имеет неопределенное поведение, если массив символов не заканчивается на '\0'
. Вы можете избежать этого, добавив дополнительное пространство для '\0'
в конце буфера.
В дополнение к предыдущим комментариям о нулевом завершении, вы также должны нести ответственность за то, что не переполнили свой собственный буфер. Он не останавливается на 8 символах, потому что ваш код не останавливается! Вам нужно что-то вроде следующего (копирование на предложение Джереми):
#define DATA_LENGTH 8
#define BUFFER_LENGTH (DATA_LENGTH + 1)
char Buffer[BUFFER_LENGTH]; //holds the byte stream
int charPos=0; //index to next character position to fill
while (charPos <= DATA_LENGTH ) { //user input event has occured
Buffer[i] = charInput;
Buffer[i+1] = '\0';
// Display a response to input
printf("Buffer is %s!\n", Buffer);
i++;
}
Другими словами, обязательно прекратите принимать данные, когда максимальная длина будет достигнута, независимо от того, что среда пытается нажмите на вас.
Если вы программируете на C или C ++, вы должны помнить, что: 1) строки заканчиваются символом \ 0. 2) C не имеет граничной проверки в строках, это просто массивы символов.