1

This is my code (I want to use string as the parameter only):

#include <iostream>
using namespace std;

int i = 0;      //to take string character by character

void parseToInteger (string s1)
{
    char convert;
    string another;
    if (convert == s1.length())     //at null character function terminates
    {
        cout<<endl;                 // prints nothing
    }
    else
    {
        convert = s1.at(i++);
        static_cast <int> (convert);
        cout<<convert;
        parseToInteger (s1); 
    }
    
}

int main ()
{
    string s0;
    cout<<"Enter a string to convert it into its integer value: ";
    getline (cin, s0);
    parseToInteger (s0);
    return 0;
    
}

This is the error I am getting:

Enter a string to convert it into its integer value: hello
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at: __n (which is 32540) >= this->size() (which is 5)

Can someone please help me? I am learning to program.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Very strange idea to use a recursive function for that task. – prapin Mar 11 '22 at 15:44
  • `char convert;` then `if (convert == s1.length())` Why are you comparing the length of the string with a char that is uninitialized (random garbage value that you are not permitted to look at)? – drescherjm Mar 11 '22 at 15:47
  • 1
    Why is `s1` passed by value? Why is `i` a global variable? – drescherjm Mar 11 '22 at 15:50
  • 1
    `static_cast (convert);` does nothing at all. The compiler should remove this line when optimizing. – drescherjm Mar 11 '22 at 15:51
  • @prapin -- For some odd reason, there are so many of these questions about recursive functions, where recursion makes no sense to use to solve the problem. The furthest thing from an actual programmer's mind is to use recursion for this. It's as if the teachers or whoever is giving this assignment can't think up a much better scenario to use recursion. – PaulMcKenzie Mar 11 '22 at 15:57
  • @PaulMcKenzie I refer the poster to [this comment](https://stackoverflow.com/questions/71441047/i-was-trying-to-convert-string-into-ascii-value-using-recursive-function-by-usi/71441228#comment126273814_71441047). ;-P – Adrian Mole Mar 11 '22 at 15:58
  • I am comparing the length of the string with convert so when null character come function go back to main () – Abdul Moeez Sultan Mar 11 '22 at 16:00
  • IMO, I think that using recursion where it really doesn't belong is what is confusing a lot of the new programmers. If the teacher or whomever actually gave a better example of recursion to the students, more of them would understand and "get it". To try and shoehorn a problem that can be solved easily with a simple loop, and ask the student to make it recursive, defeats the whole purpose of teaching the student. – PaulMcKenzie Mar 11 '22 at 16:01
  • "i" is global beacause if I put it inside the function every time I will run it its value will go 0 and i will not be able to check the string character by character – Abdul Moeez Sultan Mar 11 '22 at 16:02
  • static_cast (convert); I am doing this so char converts into int as I am trying to convert string into ASCII – Abdul Moeez Sultan Mar 11 '22 at 16:04
  • `static_cast (convert);` does a cast but throws the result away. It has no effect on the convert variable. – drescherjm Mar 11 '22 at 16:06
  • You could have made `i` a second parameter to the function with a default value of 0. `void parseToInteger (const string & s1, int i=0)` – drescherjm Mar 11 '22 at 16:07

1 Answers1

3

Your if (convert == s1.length()) is very strange. That expression is comparing an uninitialized char variable to the length of the s1 string (which will be of size_t type). What you should be doing is comparing the i variable to the length (and that i would be better defined as size_t type).

Also the static_cast <int> (convert); line does nothing. You can't change the type of a variable like that; instead, you should use the cast on the operand of the cout << in the following line. And note that, when casting a character digit to its integer value, you need to subtract the value of '0' from it.

Here's a fixed version that addresses the above issues:

#include <iostream>
#include <string> // You 'forgot' this required header

size_t i = 0; // The "size_t" type is better suited for container sizes and lengths

void parseToInteger(std::string s1)
{
    char convert;
//  std::string another; // Never used!
    if (i == s1.length()) { // Here, we've reached the end of the string
        std::cout << std::endl;                 // prints nothing
    }
    else {
        convert = s1.at(i++);
        std::cout << cout << static_cast <int> (convert - '0'); // Apply the cast here
        parseToInteger(s1);
    }
}

int main()
{
    std::string s0;
    std::cout << "Enter a string to convert it into its integer value: ";
    std::getline(std::cin, s0);
    parseToInteger(s0);
    return 0;
}

But note, there are other concerns in your code, as mentioned in the comments. First, it would be better to pass the s1 argument by reference; second: Are global variables bad?

Here's a version of your function that addresses these last two concerns:

void parseToInteger(std::string& s1, size_t i = 0)
{
    if (i == s1.length()) { // Here, we've reached the end of the string
        std::cout << std::endl;        // 'flushes' output stream
    }
    else {
        char convert = s1.at(i++);
        std::cout << static_cast <int> (convert - '0'); // Convert to int
        parseToInteger(s1, i);
    }
}

The default value (of zero) for the new i argument means that you don't have to change the call in the main function.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • No global needed when passing `parseToInteger(s1.substr(1));` and always checking length and converting the first string. – stefaanv Mar 11 '22 at 16:09
  • 2
    @stefaanv There are many ways in which the code could be improved and optimized. I am *trying* here to be helpful but, at the same time, not completely rewriting the OP's code. Although SO is, formally, a "repository of information," there is also an aspect of *education* involved. Possibly relevant: [How do I ask and answer homework questions?](https://meta.stackoverflow.com/q/334822/10871073) – Adrian Mole Mar 11 '22 at 16:11
  • @AdrianMole Thank you. This have helped my a lot. size_t is a new data type for me I'll study about it. And I know my teacher told me that global variables are bad(though I still don't know why, because so far they work great for me XD). He gave me this program as a task and restricted me to use string as an argument only. I was not able to make any logic except by using global variable, to convert string char by char. Also I didn't noticed that I was using convert uninitialized in if else, that is silly lol. – Abdul Moeez Sultan Mar 11 '22 at 16:38
  • @AbdulMoeezSultan: the problem with learning to program is that you usually work on small pieces of code where it is easy to understand where the global variables are being used. When your program is like 10000 lines with a couple of hundred of global variables and you get strange errors in your program, that's a bad time to realize why global variables are a pain. In your example, you have to remember to reset the variable every time you want to call the function. – stefaanv Mar 11 '22 at 16:50
  • @stefaanv I got your point. But what if at the end of the function, just before "return 0" inside the function of my program, if I say i = 0 (global variable I used in the above program), it will reset automatically and I will not have to worry about it then every time I call it. – Abdul Moeez Sultan Mar 11 '22 at 17:20