0

i was trying to to make a program where i was learning how to use header file and i got into an issue

salt.h

#pragma once
#include<string>
class salting {

public:
    char encrypt(std::string&);
    char decrypt(std::string&);
};

salt.cpp

#include "salt.h"
#include<iostream>

char salting::encrypt(std::string& s)
{
    size_t i = 0;
    std::cout << s;

    if (s[0] % 2 == 0) {       //shows an error of exception unhandled std::out of range
        for (char cl : s) {
            if (i % 2 != 0 && i > 2) {
                cl++;
                s.at(i) = cl;
            }
            i++;
        }
    }
    else {
        for (char cl : s) {
            if (i % 2 == 0 && i > 2) {
                cl++;
                s.at(i) = cl;
            }
            i++;
        }
    }
    return 'c';
}

char salting::decrypt(std::string& s)
{
    size_t i = 0;
    if (s.at(0) % 2 == 0) {         //shows an error of exception unhandled std::out of range
        for (char cl : s) {
            if (i % 2 != 0 && i > 2) {
                cl--;
                s.at(i) = cl;
            }
            i++;
        }
    }
    else {
        for (char cl : s) {
            if (i % 2 == 0 && i > 2) {
                cl--;
                s.at(i) = cl;
            }
            i++;
        }
    }
    return'c';
}

test.cpp

#include<iostream>
#include "salt.h"

using namespace std;

int main() {
    salting l;
    string s1 {};
    cout << "enter the string to encrypt: ";
    cin.ignore('\n',INT_MAX);
    s1.clear();
    getline(cin, s1);


    l.encrypt(s1);
    cout << endl << "the salted string is: " << s1;


    l.decrypt(s1);
    cout << endl << "the original string is: " << s1;

}

i dont know what happens as I am still learning programming the best i can state is that the getline function takes the input after which nothing happens but after i press enter 2-3 times it shows an: "Unhandled exception at 0x76804192 in test code.exe: Microsoft C++ exception: std::out_of_range at memory location 0x003AF704".Near the comment i put in salt.cpp after which if i press countinue it shows: "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention." thanks in advance.

Amit kh
  • 59
  • 1
  • 9
  • What's the value of `s.size()` before the function is called? – YSC Mar 25 '20 at 13:05
  • Could the input string perhaps be zero length, when it crashes? – Kenny Ostrom Mar 25 '20 at 13:13
  • Get rid of the `cin.ignore()` and `s1.clear()` calls. They are not needed here. – 1201ProgramAlarm Mar 25 '20 at 13:18
  • [`cin.ignore('\n',INT_MAX);`](https://en.cppreference.com/w/cpp/io/basic_istream/ignore) means you are going to ignore the next 10 characters of input. Maybe you meant `cin.ignore(INT_MAX, '\n');`? – Eljay Mar 25 '20 at 13:21
  • @YSC idk why its a 0.. – Amit kh Mar 25 '20 at 14:18
  • @1201ProgramAlarm if i remove cin.ignore then the getline function dont wait for input – Amit kh Mar 25 '20 at 14:18
  • @Eljay ok thanks but even after i converted the statement the statement it still gives same error and it takes less enter – Amit kh Mar 25 '20 at 14:21
  • @KennyOstrom yes i guess you are correct as when i asks for s.size it gives a 0 – Amit kh Mar 25 '20 at 14:21
  • @1201ProgramAlarm thanks a lot bro but the question still remains as before when i tried input with just getline it didn't stop for input what should i do for such cases?? – Amit kh Mar 25 '20 at 14:25
  • It's likely that you didn't post the right code to reproduce. Is your problem actually like https://stackoverflow.com/questions/7786994/c-getline-isnt-waiting-for-input-from-console-when-called-multiple-times – Kenny Ostrom Mar 25 '20 at 18:13

1 Answers1

0

Here is your code, somewhat reduced to illustrate the problem

#include <iostream>
#include <string>

void f(std::string s) {
    if (s.size() < 1)
        std::cout << "s[0] would correctly throw out_of_range exception" << std::endl;
}

int main()
{
    std::string s;
    (std::cin).ignore('\n', INT_MAX);
    getline(std::cin, s);
    std::cout << s.size() << std::endl;
    f(s);
}

I set this up to run with input redirected from a sample.txt file with the following line

short

The output is

0 s[0] would correctly throw out_of_range exception

Looking at the documentation http://www.cplusplus.com/reference/istream/istream/ignore/

istream& ignore (streamsize n = 1, int delim = EOF);

The value you passed to n is '\n', which is the character 10 (in ascii), so you have told it to ignore 10 characters, as a previous comment said. Therefore when it reads a 5 character input, the ignore skips all of it, leaving nothing for getline to read. This in turns leads to an out of range exception when you try to look at s[0], which is, in fact, out of range.

If you check s.size() in the function, then you can avoid looking at s[0]. Just return immediately, maybe? Your functions should always safely handle unexpected inputs like empty string.

If you comment out the ignore, then you will read the full input, and get what you expected, assuming the input you give it was what you wanted. At least, that's what happens on my build.

If you do not get the input from getline, there may be other things you haven't told us about in your code, as for example in c++ getline() isn't waiting for input from console when called multiple times or Reading two line continuously using getline function in c++

Kenny Ostrom
  • 5,639
  • 2
  • 21
  • 30
  • ohk i actually think i can understand what i did wrong there was no need of cin.ignore as i didn't used any formatted input before using getline that leaves the entire input stream empty and the string that i will enter will be ignored. Thanks a lot for the help and ofcourse i will keep in mind to handle runtime exceptions from now on. – Amit kh Mar 25 '20 at 20:10
  • in c++ it's much better to avoid exceptions. Check s.size() and don't access anything out_of_bounds – Kenny Ostrom Mar 25 '20 at 22:59