#c #buffer
#c #буфер
Вопрос:
Я пытаюсь создать приложение, которое просто выводит некоторые числа в консоль, сначала помещая их в буфер. Я просто тестирую его прямо сейчас, но (по-видимому, когда значения wchar_t копируются в bufferArray) он выдает мне это сообщение об ошибке: Выражение: строковый индекс вне диапазона
#include <Windows.h>
#include <iostream>
#include <sstream>
using namespace std;
// initialising the buffer dimensions
int width = 8;
int height = 1;
int main()
{
wchar_t bufferArray[8];
int displayNum = 00000000;
// creating access to the console buffer
wchar_t* screen = new wchar_t[width * height];
HANDLE console = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(console);
DWORD dBytesWritten = 0;
while (true)
{
// changing the displayNum int value to wchar[]
wostringstream wss;
wss << displayNum;
wstring intValue = wss.str();
// moving the values into the bufferArray wchar array (I just realized this step is unnecessary. I could just use the intValue array instead. It doesn't fix it though. I tried)
for (int i = 0; i < 8; i )
{
bufferArray[i] = intValue[i];
if (intValue[i] == 0)
bufferArray[i] = 0;
}
// putting the value into the screen buffer variable
for (int y = 0; y < height; y )
{
for (int x = 0; x < width; x )
{
screen[y * width x] = bufferArray[x];
}
}
// writing the buffer to the console
screen[width * height - 1] = '';
WriteConsoleOutputCharacter(console, screen, width * height, { 0,0 }, amp;dBytesWritten);
// adding one to the number being displayed
displayNum ;
}
return 0;
}
Комментарии:
1. Доверяйте средствам отладки вашего компилятора.
2.
int displayNum = 00000000;
это то же самое, чтоint displayNum = 0;
заполнение дополнительными 0s не имеет никакого эффекта.3. Обратите внимание, что начальный 0 здесь не имеет никакого эффекта, но он создает восьмеричный литерал. Восьмеричное 0 совпадает с десятичным 0, но
010
будет интерпретироваться как 8, а не 10.4. Длина
for (int i = 0; i < 8; i )
вашей строки равна 1, а не 8: смотрите здесь: https://ideone.com/9Jsymv таким образом, вы выходите за пределы, когда i == 1 в этой строке:bufferArray[i] = intValue[i];
5. Не уверен на 100%, каков ваш желаемый результат. Это затрудняет написание ответа, который действительно полезен для вас, в отличие от простого устранения сбоя. Сбой лучше для вас, чем какая-то скрытая логическая ошибка. По крайней мере, при сбое вы знаете, что это неправильно.
Ответ №1:
Сообщение об ошибке правильное, похоже, что вы читаете дальше конца строки. У вас есть bufferArray[i] = intValue[i]
цикл, который выполняется 8 раз, независимо от длины intValue
строки.
Похоже, что вы пытаетесь определить конец intValue
(проверяя, равно ли intValue[i]
нулю) и что-то делаете, но то, что вы делаете, неверно и не завершает цикл. Поскольку intValue
это строка, вы должны использовать intValue.size()
для получения количества содержащихся в ней символов, а не искать нулевой символ в конце. Вместо того, чтобы запускать цикл 8 раз, запустите его min(8, intValue.size())
несколько раз.
После завершения вышеупомянутого цикла вам нужно решить, что происходит bufferArray
после окончания intValue
строки. Кроме того, вам все равно может потребоваться завершить ваш bufferArray
, поскольку bufferArray
это необработанный массив символов. Но если вы действительно используете его как просто массив символов, а не строку, вам может не понадобиться завершать его нулевым завершением.
Комментарии:
1. Я думаю, вы неправильно истолковали код. Все в порядке. Я знаю, что не так и как это исправить, но я все еще не уверен, что именно пытается сделать запрашивающий, поэтому любой мой ответ может не привести к сбою, но он все равно может сделать что-то очень неправильное.
2. @user4581301 Я полагаю, вы можете быть правы, что я неправильно истолковал часть кода. Тем не менее, я почти уверен, что он читает дальше конца
intValue
строки, и этого следует избегать. 🙂 Я также не понимаю, что пытается сделать запрашивающий. Возможно, мне следует просто удалить этот ответ? (Теперь в любом случае есть комментарий, указывающий на перечитывание буфера.)3. @user4581301 это не может быть проблемой, потому что он даже не завершает ни одного цикла цикла while. Я добавлю несколько комментариев, чтобы вы могли понять, что я хочу сделать (подводя итог, я просто хочу отобразить число в консоли с числом, увеличивающимся на 1 каждый цикл цикла while. Это просто упражнение для обучения записи непосредственно в консольный буфер)
4.@nuuh вы определенно выходите за пределы строки. В этом мы с Эриком на 100% согласны. Мы немного не согласны с тем, что вы пытаетесь сделать, и как лучше это исправить. in
bufferArray[i] = intValue[i];
intValue[i]
выйдет за пределы, когдаi
будет равно 2, поэтому код завершается ошибкой в началеwhile
цикла. Что бы вы ни пытались сделать, это не сработает. Вы моглиdisplayNum
бы дополнитьsetw
иsetfill
когда вы записываете его в поток, чтобы он всегда был длиной 8 символов, и вы можете работать в обратном направлении и делитьdisplayNum
на 10 и множество других вариантов, но какой подходит лучше всего?5. Я бы не стал удалять ответ, Эрик. Он правильно диагностирует и может помочь другим людям.