C++函数中的分段错误

3

学习一些基础的C++,尝试理解函数,但是在尝试正确编写函数时遇到了很大的困难。

以下是原始代码(可以正常运行):

#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;
}

以下是我尝试将其转换为函数的代码:

#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;
    }
}

代码编译没有问题,但在输入用户信息并尝试执行后,会显示“分段错误”。

我尝试过几次重写,但都没有成功,我实在不知道如何修复它。该代码主要是读取一个字符串变量,并将其显示为一组破折号(猜词游戏)。


1
不确定是否与段错误相关,但是(1)参数“input”是按值传递的,它将被复制并且与“main()”中的变量“userinput”无关。(2)您应该在“inputUnsolved()”中返回某些内容。 - songyuanyao
1
由于inputUnsolved中没有返回语句,因此它无法编译成功 - 这是一个编译错误。因此,必须有更多的代码导致了程序崩溃。 - Rudolfs Bundulis
5个回答

3

使用引用传递而不是值传递

void inputUnsolved(string& input);

谢谢!消除了段错误。 - HHughes

2
你将参数 input 以值的方式传递给函数。这意味着它会得到 main 中变量的 副本。任何更改都只会在此副本上执行,并且不会影响原始值。
尝试改为通过引用传递,string&
另外,函数具有返回类型 string,但我没有看到函数中的 return 语句。要么返回某个值,要么将返回类型更改为 void

谢谢 Bo!我会进行这些更改,看看是否能够成功。 - HHughes

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;
   }
}

首先,不需要返回一个字符串。其次,如答案中所述,您应该通过引用发送字符串,以便更改反映在输入字符串中。
如果您想返回一个字符串,可以这样做:
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;
}

C++编译器应该为您进行优化。请注意“应该”...你永远不知道编译器的开发人员做了什么...

@songyuanyao 谢谢,已修复。 - asalic

1

你正在做一些错误的事情:

  1. 你传递了你的字符串并期望被编辑,这是错误的。
  2. 你定义了返回字符串的函数,但实际上没有返回任何内容。

你正在做一些不好的事情:

  1. using namespace std 这是一个不好的习惯。
  2. 使用 int 作为索引,它是一种有符号类型,并且小于可能的大小。

这是你问题的解决方案:

#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;
}

明白了,谢谢!我对命名空间不是很了解,只知道我的教授要求我们使用它。它的缺点是什么? - HHughes
https://dev59.com/D3M_5IYBdhLWcg3wQQ3w - Humam Helfawi

1
尝试这个,它一定会对你有用。问题在于你通过值而不是引用传递了变量输入,因为如果不是这样,无论你输入什么都不会改变为“---”。当你使用引用时,确保修改相同的变量输入。我添加的第二件事是你不需要将函数的返回值设为字符串,让它更简单,改为void即可。
  #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;
        }


    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接