Почему эта строка с указателем возвращает случайный набор символов? [Дубликат]

Переносимым способом получения 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();
}
11
задан Jonathan Leffler 8 December 2008 в 16:41
поделиться

7 ответов

Вы должны закончить строку символом \ 0. Вот почему они называются нулевыми завершенными строками.

Также целесообразно выделить 1 дополнительный символ для хранения \ 0.

26
ответ дан Toon Krijthe 21 August 2018 в 02:25
поделиться
  • 1
    Потрясающие. Благодарю. Только один вопрос: какова точка буфера [8]? – Steve 7 November 2008 в 00:16
  • 2
    buffer [8] сообщает компилятору выделить 8 байтов памяти для вашего массива. Ваша строка может быть короче, чем это (например, «buffer [4] = 0;»), но она не может (или не должна) быть длиннее. – Jeremy Ruten 7 November 2008 в 00:20
  • 3
    – Toon Krijthe 7 November 2008 в 00:20

Возможно, вы также захотите изучить stringstream.

-1
ответ дан Brian 21 August 2018 в 02:25
поделиться

Единственное, что вы передаете функции 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);

}
8
ответ дан Jeremy Ruten 21 August 2018 в 02:25
поделиться

Странно, что никто не упомянул эту возможность:

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 после цикла.

0
ответ дан Jonathan Leffler 21 August 2018 в 02:25
поделиться

Поскольку Buffer не инициализируется, он начинается со всех 9 значений мусора. Из наблюдаемых результатов 2, 3, 4, 5, 6, 7, 8 и 2 сразу следующие ячейки памяти (вне массива) четко обозначены 'T', 'T', 'W', '\0', '\0', '=', '\0', '\0', '\0'.

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

То есть строка имеет неопределенное поведение, если массив символов не заканчивается на '\0'. Вы можете избежать этого, добавив дополнительное пространство для '\0' в конце буфера.

0
ответ дан Mani Kanth 21 August 2018 в 02:25
поделиться

В дополнение к предыдущим комментариям о нулевом завершении, вы также должны нести ответственность за то, что не переполнили свой собственный буфер. Он не останавливается на 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++; 

}

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

3
ответ дан tony gil 21 August 2018 в 02:25
поделиться
  • 1
    Используйте sizeof (Buffer)! – Jonathan Leffler 7 November 2008 в 07:26
  • 2
    @Jonathan: Я предположил, что DATA_LENGTH является основной концепцией домена приложения, а размер буфера - зависимым значением, а не наоборот. Могут быть другие использования DATA_LENGTH, которые не имеют никакого отношения к Buffer, и поэтому не должны упоминать об этом. – joel.neely 25 December 2008 в 18:34
  • 3
    @ joel.neely, хотя ваш код выше некорректен (в то время как комментарий оператора отсутствует), вы заслуживаете повышения, потому что установка следующего символа на «\ 0» - это РЕШЕНИЕ. Я рекомендую редактировать «Buffer [i] = charInput; Буфер [i + 1] = '\ 0'; я ++; & Quot; для ясности, хотя ваша реализация неверна, сложнее отлаживать, потому что вы устанавливаете 2 переменных в одной строке (вопрос о стиле, я думаю). – tony gil 15 September 2012 в 14:15

Если вы программируете на C или C ++, вы должны помнить, что: 1) строки заканчиваются символом \ 0. 2) C не имеет граничной проверки в строках, это просто массивы символов.

0
ответ дан user 21 August 2018 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: