c++ - 试图忽略直到第一个字符的所有空格(迫切需要一个简单的轻推)

标签 c++

老实说,这是我完成家庭作业所需的一小段代码。我知道社区对帮助学生非常怀疑,但在过去的 5 个小时里,我一直把头靠在墙上,实际上没有完成这项任务。我从来没有在任何任务上寻求帮助,但没有人给我带来这么多麻烦。

我唯一遇到的问题是让程序去除前导空格。我想我可以处理剩下的。我不是在为我的整体任务寻求解决方案,只是对这一特定部分进行微调。

我会在这里发布完整的作业文本,但我是 不是 发布它以尝试获得完整的解决方案,我只是发布它以便其他人可以看到我必须使用的条件。

“这个作业将让你更多地练习编写函数以及如何将数字读入变量。你需要编写一个函数,将一个无符号整数读入一个 unsigned short int 类型的变量中。这将有最大值 65535 , 并且函数需要处理非法数字,函数内部不能使用“cin >>”。
数字输入的规则基本如下:

1) 跳过所有前导空格
2) 找到的第一个字符必须是数字,否则会发生错误
3)然后一次处理一个数字字符并与数字组合
4) 发现非数字时停止处理

我们将遵循这些规则,并添加错误处理和溢出。如果在数字之前进行了非法输入,则将返回错误代码“1”,如果发生溢出,即大于 65535 的数字,则将返回错误代码“2”。如果没有错误,则返回“0”。

确保 main 函数将继续循环,直到用户输入“n”或“N”表示 NO,main 应测试从名为“ReadInt”的函数返回的错误代码并显示适当的错误消息或显示编号(如果有)没有错误。在设计“ReadInt”函数时要小心,它应该是返回值并有一个引用参数。该函数需要从输入缓冲区一次处理一个字符并以正确的方式处理它。读入数字后,请确保输入缓冲区为空,否则 main 中的循环可能无法正常工作。我知道这不是提取的工作方式,但让我们这样做。

你不需要在这个作业中上交算法,但我建议你写一个。调试器也可能会有所帮助。您基本上是在重写提取运算符,因为它适用于整数。”

我的大部分代码都没有意义,因为我一直在删除东西并添加诸如疯狂之类的东西来尝试我能想到的一切。

#include <iostream>
#include <CTYPE.h>

using namespace std;

int ReadInt (unsigned short int &UserIn);

int main()
{
    int Error;
    unsigned short int UserInput;
    char RepeatProgram;

    do
    {
        Error=ReadInt(UserInput);

        if (Error==0)
            cout << "Number is " << UserInput << endl;

        else if (Error==1)
            cout << "Illegal Data Entry\n";

        else if (Error==2)
            cout << "Numerical overflow, number too big\n";

        cout << "Continue?  n/N to quit: ";
        cin >> RepeatProgram;

        cout << endl;

    } while (RepeatProgram!='N' && RepeatProgram!='n');

}

int ReadInt (unsigned short int &UserIn)
{
    int Err=0;
    char TemporaryStorage;
    long int FinalNumber=0;

    cout << "Enter a number: ";

    //cin.ignore(1000, !' '); this didn't work

    cin.get(TemporaryStorage);

    cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step

    cout << endl;

    return Err;
}

我非常感谢我可能获得的任何帮助,并希望我不会给人一种我正在寻找解决整个问题的完整免费解决方案的印象。我想自己做这件事,我只是在这个开始很多。

最佳答案

作为序言,我想说明这是一个学生提出的问题,但与大多数类型的问题不同,这是一个值得高质量答案的高质量问题,所以我会尽力去做;)。我不会尝试只回答您的具体问题,还会向您展示代码中的其他小问题。

首先,让我们一步一步地分析您的代码。或多或少就像调试器会做的那样。花点时间仔细阅读本文;)...

#include <iostream>
#include <CTYPE.h>

包括标题 <iostream><ctype.h> (由于 Windows 中 NTFS 的一些缺陷/设计决定,大写字母有效)。我建议您将第二行更改为 #include <cctype>反而。
using namespace std;

这对任何初学者/学生都可以,但不要养成习惯!出于“纯度”的目的,我会明确使用 std::沿着这个答案,好像这条线不存在。
int ReadInt (unsigned short int &UserIn);

声明一个函数 ReadInt需要引用 UserIn输入 unsigned short int并返回一个 int 类型的对象.
int main()
{

特殊功能main ;无参数,返回 int .开始功能。
    int Error;
    unsigned short int UserInput;
    char RepeatProgram;

声明变量 Error , UserInput , 和 RepeatProgram各类型 int , unsigned short int , 和 char .
    do
    {

Do-while 块。开始。
        Error=ReadInt(UserInput);

分配 ReadInt 的返回值类型 int用参数调用 UserInput类型 int&到变量 Error类型 unsigned short int .
        if (Error==0)
            std::cout << "Number is " << UserInput << endl;

Error为零,则打印出 UserInput到标准输出。
        else if (Error==1)
            std::cout << "Illegal Data Entry\n";

        else if (Error==2)
            std::cout << "Numerical overflow, number too big\n";

否则,如果发生错误,通过std::cout 向用户报告。 .
        std::cout << "Continue?  n/N to quit: ";
        std::cin >> RepeatProgram;

询问用户是要继续还是退出。将输入的字符存储在 RepeatProgram 中类型 char .
        std::cout << std::endl;

冗余,除非您想添加填充,这可能是您的目的。实际上,您最好这样做std::cout << '\n' ,但这并不重要。
    } while (RepeatProgram!='N' && RepeatProgram!='n');

上面 do-while 块的匹配表达式。如果 RepeatProgram,则重复执行给定块既不是小写字母也不是大写字母 N .
}

结束函数main .隐式返回值为零。
int ReadInt (unsigned short int &UserIn)
{

功能 ReadInt引用 UserInunsigned short int并返回一个 int 类型的对象.开始功能。
    int Err=0;
    char TemporaryStorage;
    long int FinalNumber=0;

声明变量 Err , TemporaryStorage , 和 FinalNumber各类型 int , char , 和 long int .变量 ErrFinalNumber初始化为 00 , 分别。但是,只是一件事。作业不是说输出编号存储在unsigned short int中吗? ?所以,最好是这样...
    unsigned short int FinalNumber = 0;

现在...
    std::cout << "Enter a number: ";

    //std::cin.ignore(1000, !' '); this didn't work

诶?这应该是什么? ( 错误 :中止调试器,因为这没有逻辑!**)。我希望你忘记了 //在评论之前,对吧?现在,你期待什么!' '评估为 '\0' 以外的其他人? istream::ignore(n, ch)将丢弃输入流中的字符,直到 n字符已被丢弃,ch找到,或到达文件尾。

更好的方法是......
   do
       std::cin.get(TemporaryStorage);
   while(std::isspace(TemporyStorage));

现在...
    std::cin.get(TemporaryStorage);

可以使用上述方法丢弃该行;)。

对。现在,进入到你的头明显撞到人类已知的所有固体物体的部分。让我在那里帮助你。我们有这种情况。使用上面的代码,TemporaryStorage将在 do-while 循环后保存第一个不是空格的字符。所以,我们还剩下三件事。首先,检查输入中是否至少有一位数字,否则返回错误。现在,虽然输入由数字组成,但将字符转换为整数,然后乘以加以得到实际整数。最后,这是最......咳咳......奇怪的部分,我们需要避免任何溢出。
    if (!std::isdigit(TemporaryStorage)) {
        Err = 1;
        return Err;
    }

    while (std::isdigit(TemporaryStorage)) {
        unsigned short int OverflowChecker = FinalNumber;

        FinalNumber *= 10; // Make slot for another digit
        FinalNumber += TemporaryStorage - '0'; '0' - '0' = 0, '1' - '0' = 1...

        // If an unsigned overflows, it'll "wrap-around" to zero. We exploit that to detect any possible overflow
        if (FinalNumber > 65535 || OverflowChecker > FinalNumber) {
            Err = 2;
            return Err;
        }

        std::cin.get(TemporaryStorage);
    }

    // We've got the number, yay!
    UserIn = FinalNumber;

该代码是不言自明的。如果您对此有任何疑问,请发表评论。
    std::cout << TemporaryStorage;//I'm only displaying this while I test my ideas to see if they are working or not, before I move onto the the next step

    cout << endl;

    return Err;

我应该在这里说些什么吗?反正我已经做了。只要记住拿那个std::cout在展示你的作品之前就出去了;)。
}

结束函数ReadInt .

关于c++ - 试图忽略直到第一个字符的所有空格(迫切需要一个简单的轻推),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33562552/

相关文章:

c++ - 我们需要 move 和复制作业吗

c++ - 多继承与模板接口(interface)

在 Windows 10 上使用 nuwen MinGW 的 C++17 文件系统

c++ - 在用户空间使用内核函数

c++ - 使用 openCV 时如何修复链接器错误?

c++ - 我可以使用 AVX2 分散指令来加速某些加​​载吗?

c++ - 数值食谱中显然 undefined variable

c++ - 使用带有 void 函数的模板

c++ - 一个类中如何访问全局数据成员和成员函数?

c++ - 从 std::list 中随机删除?