使用函数的12天圣诞节C ++

时间:2018-03-07 00:51:24

标签: c++

我正在初学C ++课程中,我正在尝试创建一个程序,使用两个给定的函数调用show_ordinal(int)和show_verse(int)作为赋值输出12天的圣诞歌曲。它应该调用这节经文并用它的序数后缀显示当天,然后根据用户决定从哪里开始循环剩余的经文,所以如果它是show_verse(3)它将在第3天圣诞节......一直到梨树。我开始编写函数来获取序数,但不断得到分段错误。

#include <iostream>

using namespace std;

string show_ordinal(int);
void show_verse(int);

int main()
{
    cout << show_ordinal(2) << endl;

    return 0;
}

string show_ordinal(int x)
{
    switch (x % 10)
    {

        case 1:
            if (x % 10 == 1)
            {
                cout << x << "st";
            }
            break;

        case 2:
            if (x % 10 == 2)
            {
                cout << x << "nd";
            }
            break;

        case 3:
            if (x % 10 == 3)
            {
                cout << x << "rd";
            }
            break;

        case 4:
            if (x % 10 != 1 || x % 10 != 2 || x % 10 != 3)
            {
                cout << x << "th";
            }
            break;
    }

}

通过尝试在main中调用int值为2来测试函数,我已经在它上面工作了一段时间并且无法让它工作任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

cout << show_ordinal(2) << endl; 没有为

返回任何内容
string

打印出来。它承诺返回void,但它永远不会。这是不好的形式。当函数具有非cout返回类型时,它必须在所有代码路径或函数上返回结果,并且程序生成错误。崩溃或其他段错误是常见的结果,但您可能会发现数据的无声损坏,而且更难以追踪。

而不是string您的所有结果,将结果分配给string并返回{{1}}。

答案 1 :(得分:0)

你永远不会从show_ordinal()返回一个字符串,只输出到cout。而不是使用cout,我认为你想使用x来计算一个字符串和你的计算后缀并返回:

string show_ordinal(int x) {
    string out;

    switch (x % 10) {
        case 1:
            out = to_string(x) + "st";
            break;
        case 2:
            out = to_string(x) + "nd";
            break;
        case 3:
            out = to_string(x) + "rd";
            break;
        default:
            out = to_string(x) + "th";
            break;
    }

    return  out;
}

答案 2 :(得分:0)

你应该认为自己很幸运,因为你正在做的是产生未定义的行为。如果您不相信我,请查看what OnlineGDB does to your code

问题是您定义show_ordinal的返回值为std::string,但永远不会从函数返回任何内容。 This produces undefined behavior in the C++ specification。要修复它,您可以执行以下两项操作之一:

实际上返回一个字符串。而不是转换到函数中的std::cout,而是转换为std::ostringstream,然后返回字符串化版本:

#include<string>
#include<sstream>

std::string show_ordinal(int x) {
    std::ostringstream oss;
    switch (x % 10) {

    case 1:
        // Note:  I got rid of your extraneous "if" statement.
        // "switch" is already doing that work for you.
        oss << x << "st";
        break;

    /* more cases here */

    }

    return oss.str();
}

定义函数以不返回任何内容。如果您确实希望该函数处理转换为std::cout,请使用void返回签名进行定义,并且不要将输出转移到std::cout中的main

#include<iostream>
#include<string>

void show_ordinal(int x);

int main() {
    show_ordinal(2);
}

void show_ordinal(int x) {
    switch (x % 10) {

    case 1:
        std::cout << x << "st\n";
        break;

    /* more cases here */

    }
}

这些都可以解决你的问题。

注意:还有一些事情:

  1. 请包含您正在使用的标准库的所有标题。添加#include<string>
  2. if块中不需要那些额外的case语句。如果您的代码转到case 1,则保证x % 10 == 1,所以请勿再次检查。
  3. show_ordinal不会对x % 10 > 4执行任何操作。考虑将case 4替换为default。请参阅documentation for the switch statement
  4. get out of the habit of using namespace std。它将来会让你陷入困境。