3

Learning some basic C++, trying to understand functions but having a hell of a time trying to properly write the function. Here's the original code (works fine):

#include <iostream>
#include <string>
//#include "assn.h"

using namespace std;

int main()
{
    string userinput;
    char ch1 = '-';

    cout << "Enter word: ";
    getline(cin, userinput);

    int i = 0;
    for (i; i < userinput.size(); ++i)
    {
        if (userinput.at(i) >= 'a' && userinput.at(i) <= 'z')
        userinput.at(i) = ch1;
    }

    cout << userinput << endl;
    return 0;
}

and here's the code I typed trying to make it a function:

#include <iostream>
#include <string>
//#include "assn.h"

using namespace std;

string inputUnsolved(string input);

int main()
{
        string userinput;
        cout << "Enter word: ";
        getline(cin, userinput);

        inputUnsolved(userinput);

        cout << userinput << endl;
        return 0;
}

string inputUnsolved(string input)
{
    char ch1 = '-';

    int i = 0;
    for (i; i < input.size(); ++i)
    {
        if (input.at(i) >= 'a' && input.at(i) <= 'z')
            input.at(i) = ch1;
    }
}

It compiles fine, but after entering the userinput and trying to execute, it displays "Segmentation fault"

Tried rewriting a few times with no luck and I quite honestly don't know enough to find a way to fix it. The code basically reads in a string variable and displays it as a set of dashes (hangman).

fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
HHughes
  • 55
  • 4
  • 1
    Not sure to be relevant to the segment fault error, but (1) The parameter `input` is passed by value, it'll be copied and has nothing to do with the variable `userinput` in `main()`. (2) You should return sth in `inputUnsolved()`. – songyuanyao Mar 10 '16 at 08:31
  • 1
    It can't compile fine since you don't have a return statement in `inputUnsolved` - and that is a compilation error. So there must be more code that makes it crash. – Rudolfs Bundulis Mar 10 '16 at 08:34

5 Answers5

3

Pass by reference instead

void inputUnsolved(string& input);
Digital_Reality
  • 4,488
  • 1
  • 29
  • 31
2

You pass the parameter input by value to the function. That means that it gets a copy of the variable in main. Any changes is performed on this copy only, and does not affects the original value.

Try passing by reference instead, string&.

Also, the function has a return type string, but I don't see any return statement in the function. Either return some value or change the return type to void.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

Try this:

#include <iostream>
#include <string>
//#include "assn.h"

using namespace std;

void inputUnsolved(string &input);

int main()
{
        string userinput;
        cout << "Enter word: ";
        getline(cin, userinput);
        inputUnsolved(userinput);
        cout << userinput << endl;
        return 0;
}

void inputUnsolved(string &input)
{
   char ch1 = '-';
   for (int i=0; i<input.size(); ++i)
   {
      if (input.at(i) >= 'a' && input.at(i) <= 'z')
         input.at(i) = ch1;
   }
}

First there is no need to return a string. Second, as said in an answer you should send the string by reference so the changes are reflected in the input string.

If you want to return a string, you can do this:

string inputUnsolved(string input)
{
   char ch1 = '-';
   for (int i=0; i<input.size(); ++i)
   {
      if (input.at(i) >= 'a' && input.at(i) <= 'z')
         input.at(i) = ch1;
   }
   return input;
}

The c++ compiler should optimize it for you. Please take into account should... you never know what the compiler's devs did...

asalic
  • 664
  • 3
  • 6
1

You are doing some wrong things:

  1. you pass your string and expect to be edited which is wrong.
  2. you define your function to return string which is not returning anything

You are doing some bad things:

  1. using namespace std this bad practise.
  2. using int for indexing which is a signed type and less than the possible size.

This is the solution to your problems:

#include <iostream>
#include <string>


std::string inputUnsolved(const std::string& input);

int main()
{
        std::string userinput;
        std::cout << "Enter word: ";
        std::getline(std::cin, userinput);

        userinput=inputUnsolved(userinput);

        std::cout << userinput << std::endl;
        return 0;
}

std::string inputUnsolved(const std::string& input)
{
    std::string result;
    result.reserve(input.size());
    char ch1 = '-';

    for (std::size_t i=0; i < input.size(); ++i)
    {
        if (input.at(i) >= 'a' && input.at(i) <= 'z'){
            result.push_back(ch1);
        }
        else{
            result.push_back(input.at(i));
        }
    }
    return  result;
}
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
  • Got it, thanks! I dont know much about namespace, I just know my professor asked us to use it. What about it isnt optimal? – HHughes Mar 10 '16 at 08:56
  • http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – Humam Helfawi Mar 10 '16 at 08:57
1

Try this it will work for you for sure, the problem was that you passed the variable input by value instead of reference, because if not, no matter what you entred it will not change to "---", when you use refrence you make sure you modify the same variable entred. The second thing that i added is that you dont need to make the return value of your function a string, make it easier and make it void instead.

  #include <iostream>
    #include <string>
    //#include "assn.h"

    using namespace std;

    void inputUnsolved(string& input);

    int main()
    {
            string userinput;
            cout << "Enter word: ";
            getline(cin, userinput);

            inputUnsolved(userinput);

            cout << userinput << endl;
            return 0;
    }

    void inputUnsolved(string& input)
    {
        char ch1 = '-';

        int i = 0;
        for (i; i < input.size(); ++i)
        {
            if (input.at(i) >= 'a' && input.at(i) <= 'z')
                input.at(i) = ch1;
        }


    }
Mourad
  • 474
  • 4
  • 10