【问题标题】:How to check for a binary to decimal program if the input is indeed a binary number (only 1s and 0s)?如果输入确实是二进制数(只有 1 和 0),如何检查二进制到十进制程序?
【发布时间】:2021-07-19 04:30:34
【问题描述】:

想编写一个程序将二进制数转换为十进制数,但我想确保,如果用户输入类似 250 的内容,应该会出现错误消息并要求输入真实的二进制数。

我怎么能这样做,我真的找不到解决方案。我已经设法屏蔽了“a”左右的字符,但是这个非常棘手!

感谢您的帮助!

我用这段代码试过了,但是 if 语句似乎总是错误的,任何解释为什么会这样?

void isBinary(char s[MAX])

{

int i = 0; for(i = 0; i

{




    if(s[i] == 0 || s[i] == 1)

    {

        continue;


    }

    else {

        printf("Error!\n");
        break;


        }






}

}

【问题讨论】:

  • 你使用的是c还是c++?你试过什么?你在哪里卡住了?请出示minimal reproducible example
  • 您确实应该发布您使用的语言。对于 C++,只需一个 std::all_of 调用即可。
  • 对不起,我以为我已经输入了:in normal C
  • 我用这个功能试过了,可惜没用。你能帮我找出错误吗(我对编码很陌生)?

标签: c binary


【解决方案1】:

你可以把它放在一个函数中来验证你的数据,但是看起来很简单,像这样:

string line;

getline(cin, line);
for (char c: line) {
    if (c != '0' && c != '1') {
        cout << "Please input binary only." << endl;
        exit(1);
    }
}

【讨论】:

  • 如果整数也包含某些数字,是否可以检查它?
【解决方案2】:

代码

这是一个使用 C 的示例,没有任何动态分配:

#include <stdio.h>

int main()
{
    _Bool haserror = 0;
    int result; // the number
    do
    {
        result = 0; // reset the number
        haserror = 0; // reset error
        _Bool isEmpty = 1; // this means that the user just hit enter and didn't specify any number
        char c; // we process the string character by character
        while ((c = getchar()) != '\n') // read until the newline (If you are using Windows, you might need to change this, because Windows uses "\r\n" for newlines)
        {
            isEmpty = 0; // there is some imput

            if (c != '0' && c != '1')
            {
                printf("This is unacceptable!\n");
                while (getchar() != '\n'); // clear out the garbage

                haserror = 1; // there's an error, loop
                break;
            }

            result <<= 1; // the actual conversion from binary to decimal, using advanced binary operations
            result |= (c - '0');
        }

        if (isEmpty)
        {
            printf("Nothing is unacceptable, too!\n");
            haserror = 1;
        }
    } while (haserror); // loop until there isn't any error

    printf("%d\n", result);
}

这缺少一些功能(Windows 换行符、EOF 处理),但显示了主要逻辑。

数学

假设我们已经阅读了数字1010,并且需要在末尾添加数字1。我们需要为新数字创建空间,因此我们将其向左移动一位。

Before: 1010
After:  10100

然后我们用(c - '0') 得到实际数字。如果c'0',则'0' - '0'0。如果c'1',那么它的ASCII 值就是49,减去'0' 的值,即ASCII 中的4849 - 48 = 1,所以'1'会被转换成1,没错。

然后我们或它。

10100 OR
00001
-----
10101

【讨论】:

  • 嘿,谢谢你解释清楚的例子。有没有办法让它变得更简单、更短?
  • 此解决方案不使用任何固定大小的缓冲区或动态分配。与其他实现相比,这是一个很大的优势。使用缓冲区,您需要先读取数据,然后再处理数据。您访问此数据两次(或更多)。通过这种实现,您在读取数据的同时进行处理,因此您只需读取一次数据,速度更快。
【解决方案3】:

错误答案

#include <stdio.h>
#include <stdlib.h>

_Bool validate(const char * c);

int main()
{
    char buffer[10]; // very ugly fixed-size buffer
    while (1)
    {
        if (scanf("%9s", buffer) == EOF) // EOF means reading error, propably not recoverable
            return 1;

        while ((readError = getchar()) != '\n' && readError != EOF); // clear out the garbage
        if (readError == EOF) // there is no more data to read
            return 1;
        if (!validate(buffer)) // main work is done via strtoul(), but it returns 0 on error, so there isn't any way to distinguish bad imput from user typing 0, so we need to check manually
        {
            printf("This is unacceptable!\n");
            continue;
        }
        printf("%ld\n", strtoul(buffer, 0, 2)); // strtoul converts the string to unsigned long
        break;
    }
}

_Bool validate(const char * c)
{
    for (; *c != 0; c++) // iterate through all character, checking if they're '0' or '1'
    {
        if (*c != '0' && *c != '1')
            return 0;
    }
    return 1;
}

此代码处理数据 3 次(scanf() 读取它,validate() 验证它,strtoul() 提取数字)。我的其他解决方案更长但更好。

这次我添加了EOF检查。

同样,Windows 换行符可能会有些复杂。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 2013-09-12
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 2017-11-08
    相关资源
    最近更新 更多