String subscript out of range c как исправить

String subscript out of range C++ Решение и ответ на вопрос 1930685

Маринчик

0 / 0 / 3

Регистрация: 12.10.2012

Сообщений: 150

1

02.03.2017, 22:24. Показов 2443. Ответов 9

Метки нет (Все метки)


Разбираю пример, который дала препод в примерах к лекциям..Пример по коду Виженера.. Пару раз запустился-результат выводился.Исправила только алфавит на кириллицу,и поставила на некоторые строки коменты.Теперь консолька запускается, начальный этап проходит, но потом результат не выводится, и консолька просто виснет..и выбивает это сообщение про «Debug assertion failed : string subscript out of range»

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// 11.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <string>
#include <iostream>
#include <conio.h>
 
using namespace std;
 
int main()
{
    string TEXT, KEY, D = "";
    string A = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ-_,."; //наш алфавит
    setlocale(LC_ALL, "Rus");
    cout << "Введите предложение: ";
    cin >> TEXT;
    KEY =  "МАРИНА";
    int *F = new int[TEXT.size()];
    int *G = new int[TEXT.size()];
    int key = KEY.size(); //делаем замену переменных для удобства
    int text = TEXT.size();
    
    if (text >= key)//Первое условие. Если длина вводимого слова больше, либо равна длине ключа
    {
        for (int i = 0; i < (text / key); i++)
        {
            D = D + KEY; //Записываем целое количество ключа. Растягивая ключ по длине слова.
        }
        for (int j = 0; j < (text%key); j++)
        {
            D = D + KEY[j];
        }
    }
    else  //Иначе если ключ длиннее слова, укорачиваем ключ до длины слова.
    {
        for (int s = 0; s < text; s++)
        {
            D = D + TEXT[s];
        }
    }
 
//cout<<"Распишем ключ под текст: ";
//cout << D << endl;
 
    for (int k = 0; k < text; k++)//Здесь мы уже начинаем шифровать.
    {
        for (int n = 0; n < 36; n++)
        {
            if (TEXT[k] == A[n])// Смысл заключается втом, что мы ищем номер буквы во вводимом ключе и номере, 
            {
                F[k] = n;
            }
 
            if (D[k] == A[n])
            {
                G[k] = n;
            } ///И после чего записываем их в массив
 
        }
    }
 
    int e = 0; //Для суммы номеров символов. Чтобы при достижении 36 буквы или символа, программа шла по кругу, начиная с первого номера
bool shifr;
cout<<"для шифрования введите 1, для расшифровки нажмите 0: ";
cin>>shifr;
if (shifr==1){
    for (int u = 0; u < text; u++)
    {
        e = ((F[u] + G[u]) % 36);
        TEXT[u] = A[e];
    }
 }
else
    for (int u = 0; u < text; u++)
    {
        e = ((F[u] - G[u]));
        if (e<0)
            e+=36;
        TEXT[u] = A[e];
    }
    cout << "Зашифрованное слово: " << TEXT << endl;
 
    
    _getch();
    return 0;
 
}

По пошаговой отладке понимаю что проблема вроде как с загрузкой символов на 81 строчке.. А как сделать чтоб работало нормально-правильно?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

02.03.2017, 22:24

9

284 / 232 / 114

Регистрация: 07.09.2016

Сообщений: 584

02.03.2017, 22:34

2

в вашей 81 строке ничего такого, что может родить ассерт не происходит.
поведение вашей программы зависит от того, что вы там вводите. я вбил что-то от балды и ассертов не было.
в таких случаях вводные данные надо писать тут, а еще лушче тупо хардкодить, вместо того, чтобы запрашивать
у пользователя их ввод. сильно экономит время всем. после отладки хардкод можно убирать.
ну и до кучи почитайте третий пост из темы:
Как пользоваться отладчиком (в Visual Studio)



0



Lambont

93 / 91 / 62

Регистрация: 23.11.2013

Сообщений: 242

02.03.2017, 22:48

3

Особо не вникал в код, но, пройдя отладчиком, у вас после 69 строки

C++
1
        e = ((F[u] + G[u]) % 36);

переменная e в любом случае будет содержать очень большое число, которое потом используется как индекс символа в строке, а размер строки явно меньше чем это число, вот и ошибка выхода за границы string.



0



nd2

3433 / 2812 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

02.03.2017, 22:54

4

Цитата
Сообщение от Маринчик
Посмотреть сообщение

По пошаговой отладке понимаю

Найди точное место в коде, где ошибка вылетает. Судя по ошибке, где-то выходишь за границу string, значит внимание к местам, где к string A по индексу обращаешься. Например:

C++
1
2
3
4
        e = ((F[u] - G[u]));
        if (e<0)
            e+=36;
        TEXT[u] = A[e];



0



1270 / 1027 / 470

Регистрация: 25.12.2016

Сообщений: 3,333

02.03.2017, 22:55

5

Цитата
Сообщение от Lambont
Посмотреть сообщение

переменная e в любом случае будет содержать очень большое число

От нуля до 35 — вроде не очень большое. А в массиве А как раз 36 элементов.
Точнее, 37 элементов, так что делить по модулю нужно на 37, если я правильно понял алгоритм.



0



3433 / 2812 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

02.03.2017, 22:57

6

Цитата
Сообщение от Lambont
Посмотреть сообщение

еременная e в любом случае будет содержать очень большое число

Тут, как раз, не будет. Здесь от 0 до 35.

Добавлено через 55 секунд

Цитата
Сообщение от likehood
Посмотреть сообщение

А в массиве А как раз 36 элементов.

37.



0



93 / 91 / 62

Регистрация: 23.11.2013

Сообщений: 242

02.03.2017, 23:05

7

Цитата
Сообщение от likehood
Посмотреть сообщение

От нуля до 35 — вроде не очень большое. А в массиве А как раз 36 элементов.

Цитата
Сообщение от nd2
Посмотреть сообщение

Тут, как раз, не будет. Здесь от 0 до 35.

Странно, у меня явно переменная е после 69 строки всегда отрицательное значение имеет, чтобы я не вводил, и именно здесь мне бросает исключение выхода за границы



0



3433 / 2812 / 1249

Регистрация: 29.01.2016

Сообщений: 9,426

02.03.2017, 23:13

8

Цитата
Сообщение от Lambont
Посмотреть сообщение

е после 69 строки всегда отрицательное значение имеет,

Отрицательный индекс — это тоже выход за границу.



0



likehood

1270 / 1027 / 470

Регистрация: 25.12.2016

Сообщений: 3,333

02.03.2017, 23:17

9

Кажется понял в чём дело. Если строка содержит только символы алфавита, то программа не вылетает. Но если есть хотя бы один пробел или например цифра, то 51 строка не будет выполнена и этот элемент массива не будет инициализирован. Отсюда и все глюки.

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

C++
1
2
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

Ну и естественно, шифруемый текст должен содержать только большие буквы.


Я бы вообще сначала отладил программу для английского алфавита, а потом при желании добавил поддержку русского.



1



Lambont

93 / 91 / 62

Регистрация: 23.11.2013

Сообщений: 242

02.03.2017, 23:18

10

Цитата
Сообщение от nd2
Посмотреть сообщение

Отрицательный индекс — это тоже выход за границу.

Вот вот, я и о том же. Я даже больше скажу, у меня и после 76 строки

C++
1
        e = ((F[u] - G[u]));

в е космические числа, видимо в массивах F и/или G что-то не-то происходит… дойду до дома — подробнее посмотрю тогда



0



Member Avatar

13 Years Ago

Hi Everybody,

If someone could help me with this problem, I would really appreciate it. I’m a newbie and trying to finish an assignment. I’ve gotten stuck on one thing and can’t seem to find a way out of it. I’ve already done the searches and spent at least 5-6 hours on this little problem alone. I imagine it’s something easy to solve for you guys:

In the code below, every thing works fine until I try to increment the ‘k’ variable (trying to read through a string character by character). Then I get the following warning:

Expression: string subscript out of range

Does anybody know what I can do to solve this?

int main()
{

string keyword;
int check;
int i=0;
int k=0;


char abcd[ARRAY_SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXY";


ifstream infile;
ofstream outfile;
infile.open ("C:\Users\achirri\Documents\MP6proj.txt");
outfile.open ("I:\C++\MP6proj.txt");





infile >> keyword;



char passkey[ARRAY_SIZE];


for(i = 0; i < ARRAY_SIZE; i++)
    {
		k++;
	check = check_passkey(passkey, ARRAY_SIZE, keyword[k]);
    if (check == 0)   
       passkey[i] = keyword[k];
	abcd_erase(abcd, keyword[k], ARRAY_SIZE);


    }

Edited

13 Years Ago
by Nick Evan because:

Add code-tags


Recommended Answers

Code tags:

[code]

// code goes here

[/code]

So ARRAY_SIZE is 25? 26? Is it defined somewhere? It’s not listed here, and a lot of other stuff isn’t listed either, so it’s impossible to run and it’s hard to see what’s going on. We also don’t …

Jump to Post

Again, use code tags. See post 2 for how. Code is hard to read otherwise.

You got rid of the k++ line, so now k is always 0. Accident? What is this program supposed to do? If you have a keyword called «Phenomenon», passkey and abcd are supposed to …

Jump to Post

All 6 Replies

Member Avatar


VernonDozier

2,218



Posting Expert



Featured Poster


13 Years Ago

Code tags:

[code]

// code goes here

[/code]

So ARRAY_SIZE is 25? 26? Is it defined somewhere? It’s not listed here, and a lot of other stuff isn’t listed either, so it’s impossible to run and it’s hard to see what’s going on. We also don’t know what the input file’s contents are, so we have no idea what keyword is. But if keyword is «house», the program’s going to crash if k is 5 or greater since «house» has 5 letters (therefore it has valid character indexes of 0 through 4).

Without seeing more, I’m guessing that’s your problem. If the length of keyword is less than ARRAY_SIZE, it’s not going to get through the loop without crashing.

Member Avatar

13 Years Ago

Sorry about that. Here’s the full code. I thought the problem could be
figured out with that snippet.

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <cctype>

using namespace std;

const int ARRAY_SIZE=26;
const int MAX_ROW=5;
const int MAX_COL=5;


int check_passkey(char p_key[], int length, char searchitem);
void abcd_erase(char a_to_y[], char searchitem, int length);



int main()
{

string keyword;
int check;
int i=0;
int k=0;

char abcd[ARRAY_SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXY";


ifstream infile;
ofstream outfile;
infile.open ("C:\Users\achirri\Documents\MP6proj.txt");
outfile.open ("I:\C++\MP6proj.txt");





infile >> keyword;



char passkey[ARRAY_SIZE];


for(i = 0; i < ARRAY_SIZE; i++)
    {
		
	check = check_passkey(passkey, ARRAY_SIZE, keyword[k]);
    if (check == 0)   
		passkey[i] = keyword[k];
	abcd_erase(abcd, keyword[k], ARRAY_SIZE);
	

    }


return 0;

}


int check_passkey(char p_key[], int length, char searchitem)
{
    int loc;
    bool found = false;

    for (loc = 0; loc < length; loc++)
    if (p_key[loc] == searchitem)
        {
           found = true;
           break;
        }

    if (found)
       return 1;
    else   
       return 0;
}


void abcd_erase(char a_to_y[], char searchitem, int length)
{
   

    int loc;
    bool found = false;

    for (loc = 0; loc < length; loc++)
    if (a_to_y[loc] == searchitem)
        {
           found = true;
           break;
        }




    if(found)
      for (loc; loc < length; loc++)          //Should be length - 1 ?
        a_to_y[loc] = a_to_y[loc + 1];     

}

Edited

13 Years Ago
by Nick Evan because:

Added code-tags (again)

Member Avatar

13 Years Ago

Oh and «keyword» is being pulled from an external file and is just a
single word, which could be anything, in this case the word is ‘Phenomenon’.

Member Avatar


VernonDozier

2,218



Posting Expert



Featured Poster


13 Years Ago

Again, use code tags. See post 2 for how. Code is hard to read otherwise.

You got rid of the k++ line, so now k is always 0. Accident? What is this program supposed to do? If you have a keyword called «Phenomenon», passkey and abcd are supposed to be changed to what when you’re all done?

Edited

13 Years Ago
by VernonDozier because:

n/a

Member Avatar

13 Years Ago

Okay, thanks for the tips on the code tags. I will look at that. And I accidentally dropped the k++ while trying to work on this problem. Didn’t mean to post without it. Sorry this is confusing. The problem I am trying to solve is to input a word from a file, to pass the characters of that word one by one to an array, without repeating any letters, so a word like ‘vacuum’ has only one of the ‘u’s put in the array. I have a function defined that parses the array to see if a letter already exists in it and passes that info back to the main function to varify. That works okay. The problem I am having is figuring out how to increment the letters of the word I am putting in the array. I was trying to use the k++ to increment through the string letter by letter, but for some reason this is not allowed. I don’t get an error unless I try to increment in this way. So, I assume I must be going out of range in some way, but don’t have much of a clue of what to do about it. Any kind of work around would be helpful.
Thanks.

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <cctype>

using namespace std;

const int ARRAY_SIZE=26;
const int MAX_ROW=5;
const int MAX_COL=5;


int check_passkey(char p_key[], int length, char searchitem);
void abcd_erase(char a_to_y[], char searchitem, int length);



int main()
{

string keyword;
int check;
int i=0;
int k=0;

char abcd[ARRAY_SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXY";


ifstream infile;
ofstream outfile;
infile.open ("C:\Users\achirri\Documents\MP6proj.txt");
outfile.open ("I:\C++\MP6proj.txt");





infile >> keyword;



char passkey[ARRAY_SIZE];


for(i = 0; i < ARRAY_SIZE; i++)
{

check = check_passkey(passkey, ARRAY_SIZE, keyword[k]);
if (check == 0)
passkey[i] = keyword[k];
abcd_erase(abcd, keyword[k], ARRAY_SIZE);
k++

}


return 0;

}


int check_passkey(char p_key[], int length, char searchitem)
{
int loc;
bool found = false;

for (loc = 0; loc < length; loc++)
if (p_key[loc] == searchitem)
{
found = true;
break;
}

if (found)
return 1;
else
return 0;
}


void abcd_erase(char a_to_y[], char searchitem, int length)
{


int loc;
bool found = false;

for (loc = 0; loc < length; loc++)
if (a_to_y[loc] == searchitem)
{
found = true;
break;
}




if(found)
for (loc; loc < length; loc++) //Should be length - 1 ?
a_to_y[loc] = a_to_y[loc + 1];

}

Member Avatar


VernonDozier

2,218



Posting Expert



Featured Poster


13 Years Ago

One, if you are new to C++, I would suggest not using C-Strings at all for this. C-Strings require you to adjust the null terminator. Regular strings do not. You use both in this program. It’s easy to get confused.. I would convert all C-strings to strings.

Two, some type of output would be informative. You have variables manipulated, but never displayed. A display like «Vacuum stripped of all duplicate letters is Vacum» would help. Say explicitly in comments what the display should be.

Three, keep in mind that C++ is case-sensitive. Your array is ‘A’ through ‘Y’. ‘U’ is not ‘u’, so if you compare the two with the == operator, they are not the same. Consider using the toupper function from the cctype library to force capitalization.

Four, if you want to avoid illegal subscript errors, use the strlen function for C strings or the length function from string. If the index you are checking is greater than the length, you could have problems.

string a = "abcdefghij";
string b = "gghhi";
int i = 0;
int k = 0;

while (i < a.length() && k < b.length())
{
    char aChar = a[i];  // no subscript-out-of-range problem
    char bChar = b[k];  // no subscript-out-of-range problem
    // do stuff
}

cout << "b stripped is " << b;  // "gghhi stripped is ghi"


Reply to this topic

Be a part of the DaniWeb community

We’re a friendly, industry-focused community of developers, IT pros, digital marketers,
and technology enthusiasts meeting, networking, learning, and sharing knowledge.

Я новичок в языке C ++, и я искал четкий ответ на мою проблему, но безрезультатно. Что я пытаюсь сделать, это получить substr значение строки, которая является одной строкой в ​​текстовом файле. Когда я запускаю такую ​​компиляцию, я получаю первые двенадцать букв предложения, и у меня нет проблем с этим:

a[count] = sentence.substr(0,12);

но когда я пытаюсь изменить pos от 0 к любому другому значению, например:

a[count] = sentence.substr(1,12);

Я получаю ошибку:

прекращение вызова после выброса экземпляра std :: out_of_range
what (): basic_string :: substr: _pos (который равен 1) this -> size () (который равен 0)

Я проверил это с YT и онлайн-гидами, и ни у кого не было проблем с substr,
Есть идеи?

РЕДАКТИРОВАТЬ:
Извините за причину путаницы. Это часть кода:

string sentence;
string a[10000];
string next_line[10000];

main()
{

int count = 1;fstream file;
file.open("converted.txt",ios::in);

while(!file.eof())
{
getline(file, line);
next_line[count] = line;
sentence = next_line[count];

a[count] = sentence.substr(1,12);

count++;
}

}

-4

Решение

От feof

Этот индикатор обычно устанавливается предыдущий операция в потоке
который пытался прочитать в конце файла или после него.

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

От зиЬзЬг

Подстрока — это часть объекта, которая начинается с символа
позиция pos и символы len (или до конца строки,
что наступит раньше)
.

Так что если вы использовали substr с первым параметром 0 все было в порядке, оно было пропущено. Но если вы передали 1 в качестве первого параметра, который был больше, чем строка, содержащая символы, было сгенерировано исключение.


Вот правильное чтение из файла

#include <iostream>
#include <fstream>

using namespace std;

string sentence;
string a[10000];
string next_line[10000];

int main()
{

int count = 1;
std::string line;

fstream file;
file.open("test.txt",ios::in);

while(getline(file, line))
{
next_line[count] = line;
sentence = next_line[count];

a[count] = sentence.substr(1,12);

count++;
}
}

1

Другие решения

Других решений пока нет …

Нижний индекс строки С++ вне диапазона

Пожалуйста, помогите с отладкой. Это дает мне ошибку «строка индекса вне диапазона ошибок».

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

Вот код:

#include<iostream>
#include<string>
using namespace std;

void insertionSort(string &text, int size) {
  char temp;
  int i;
  for(int j=1;j<size;j++)
  {
    //text.push_back(temp);
    temp=text[j];
    i=j-1;
   while(i>=0 && text[i]>temp)
 {

 text[i+1]=text[i];
  i--;
 }
    text[i+1]=temp;
  }
}

int main()
{
  string text="this a just text need to be sorted";

  int size = text.length();
  insertionSort(text,size);
  cout<<text<<endl;
  return 0;
}

Ошибка отладки утверждения!

Строка:1441:

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

я должен изменить text[i+1]=text[j] в text[i+1]=text[i];

Замените

while(text[i]>temp && i>=0)

с

while(i>=0 && text[i]>temp)

Причина:

Когда я становится отрицательным, т.е. i == -1, то сначала проверьте i>=0 вместо проверки на text[i]>temp (который пытается получить доступ к элементу массива в позиции -1 и выходит за пределы диапазона).

EDIT:

также заменить

text[i+1]=text[j];

с

text[i+1]=text[i];

Почему так ? : В сортировка вставок если у нас есть записи больше, чем text[j] в нижней части (т. е. от 0 до j-1), то нам нужно продвинуть эти записи вперед и остановиться в точке, когда у нас больше нет элементов больше, чем text[j].

ответ дан 15 апр.

Вы должны изменить эту инструкцию:

text[i+1]=text[i];

ответ дан 15 апр.

После появления j == 1 ваш цикл while начинается с i==0, затем вы уменьшаете i в цикле, то при следующем выполнении цикла вы проверяете наличие text[i], что неверно (i == -1 здесь)

Для исправления необходимо проверить правильность i первый:

while(i >=0 && text[i] > temp) {
  // ...
}

Это правильно, потому что && действует правило короткого замыкания: если первый операнд (i>=0 в данном случае) приводит к false, остальное выражение (text[i] > temp) не оценивается

ответ дан 15 апр.

У вас есть информация о проблеме. Простой способ решить эту проблему — поместить несколько операторов печати, чтобы узнать значения индекса, используемые с массивом строк.

Еще один комментарий: пожалуйста, не передавайте длину строки, потому что если вы вызовете text.length(); внутри функции перед ее изменением можно получить длину строки.

ответ дан 15 апр.

Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками

c++
string
algorithm
subscript

or задайте свой вопрос.

Понравилась статья? Поделить с друзьями:
  • String or binary data would be truncated sqlstate 22001 error 8152
  • String indices must be integers как исправить
  • Stop code whea uncorrectable error
  • Stop code acpi bios error
  • Stop chassis error ошибка на туарег зимой