试图忽略第一个字符之前的所有空格(迫切需要一个简单的轻推)

Trying to ignore all whitespace up to the first character (desperately needing a simple nudge)

本文关键字:迫切需要 一个 空格 简单 第一个 字符      更新时间:2023-10-16

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

我遇到的麻烦只是让程序去掉前导的空格。 我想我可以处理其余的。 我不是在要求解决我的整体任务,只是对这一特定部分的推动。

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

"这个家庭作业将给你更多的练习来编写函数,以及如何将数字读入变量。您需要编写一个函数,该函数将无符号整数读取到无符号短整型类型的变量中。这将具有最大值 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 Entryn";
        else if (Error==2)
            cout << "Numerical overflow, number too bign";
        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;

声明变量 ErrorUserInputRepeatProgram,类型分别为 intunsigned short intchar

    do
    {

边做边块。开始。

        Error=ReadInt(UserInput);

将使用类型为 int& 的参数 UserInput 调用的类型为 intReadInt 的返回值分配给类型为 unsigned short int 的变量Error

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

如果Error为零,则打印出UserInput到标准输出。

        else if (Error==1)
            std::cout << "Illegal Data Entryn";
        else if (Error==2)
            std::cout << "Numerical overflow, number too bign";

否则,如果发生错误,请通过 std::cout 的方式向用户报告。

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

查询用户是否要继续或退出。将输入字符存储在类型为 charRepeatProgram中。

        std::cout << std::endl;

冗余,除非您要添加填充,这可能是您的目的。实际上,你最好做std::cout << 'n',但这并不重要。

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

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

}

结束函数main .隐式返回值为零。

int ReadInt (unsigned short int &UserIn)
{

函数 ReadInt 采用引用UserIn unsigned short int并返回类型为 int 的对象。开始函数。

    int Err=0;
    char TemporaryStorage;
    long int FinalNumber=0;

声明变量ErrTemporaryStorageFinalNumber分别类型intcharlong int。变量 ErrFinalNumber 分别初始化为 00。但是,只有一件事。作业不是说输出数字存储在unsigned short int中吗?所以,更好的是这个...

    unsigned short int FinalNumber = 0;

现在。。。

    std::cout << "Enter a number: ";
    //std::cin.ignore(1000, !' '); this didn't work

啊?这应该是什么?(错误:中止调试器,因为这不会产生逻辑!我期待你只是忘记了评论前的//,对吧?现在,除了''之外,您期望!' '评估什么? 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 .

您可以使用

std::ws 跳过流中的前导空格。例如:

std::cin >> std::ws;

这种对>>的使用只是调用流上的操纵器std::ws。为了满足教师的要求,您可以直接调用它:

std::ws(std::cin);

格式化输入会自动跳过空格。请注意,还应始终检查输入是否成功:

if (std::cin.get(TemporaryStorage)) {
    ...
}