Выражение: строковый индекс вне диапазона консольного буфера

#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. Я бы не стал удалять ответ, Эрик. Он правильно диагностирует и может помочь другим людям.