为什么“\ b”没有清除左边的一个字符?

时间:2013-10-02 01:33:18

标签: c

我试图用文字打印01-99而且我有点成功。

以下是源代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char a, b;
    char *digit1;
    char *digit2;

    // get digit character by character
    scanf("%c%c", &a, &b);

    switch(a) {
        case '1':
            switch(b) {
                case '0':
                    digit1 = "ten";
                    break;

                case '1':
                    digit1 = "eleven";
                    break;

                case '2':
                    digit1 = "twelve";
                    break;

                case '3':
                    digit1 = "thirteen";
                    break;

                case '4':
                    digit1 = "fourteen";
                    break;

                case '5':
                    digit1 = "fifteen";
                    break;

                case '6':
                    digit1 = "sixteen";
                    break;

                case '7':
                    digit1 = "seventeen";
                    break;

                case '8':
                    digit1 = "eighteen";
                    break;

                case '9':
                    digit1 = "nineteen";
                    break;

                default:
                    digit1 = "";
                    break;
            }
            break;

        case '2':
            digit1 = "twenty-";
            break;

        case '3':
            digit1 = "thirty-";
            break;

        case '4':
            digit1 = "forty-";
            break;

        case '5':
            digit1 = "fifty-";
            break;

        case '6':
            digit1 = "sixty-";
            break;

        case '7':
            digit1 = "seventy-";
            break;

        case '8':
            digit1 = "eighty-";
            break;

        case '9':
            digit1 = "ninty-";
            break;

        default:
            digit1 = "";
    }

    switch(b) {
        case '1':
            digit2 = "one";
            break;

        case '2':
            digit2 = "two";
            break;

        case '3':
            digit2 = "three";
            break;

        case '4':
            digit2 = "four";
            break;

        case '5':
            digit2 = "five";
            break;

        case '6':
            digit2 = "six";
            break;

        case '7':
            digit2 = "seven";
            break;

        case '8':
            digit2 = "eight";
            break;

        case '9':
            digit2 = "nine";
            break;

        case '0':
            digit2 = "\b";
            break;

        default:
            digit2 = strcpy(digit1, "\b");
    }

    if (a != 1) {
        printf("%s%s\n", digit1, digit2);
    }
    else {
        printf("%s\n", digit1);
    }

    return 0;
}

我从20-99成功打印到现在。但是有一个错误。如果我输入20,30,40中的任何一个... -未被删除,因为我应该使用\b删除它。

3 个答案:

答案 0 :(得分:4)

你可以替换

digit2 = "\b";

通过

if (digit1[0] != '\0')
    digit1[strlen(digit1) - 1] = '\0';

可有效删除digit1中的尾随字符。

由于这完全适用于字符串级别,因此您可以避免依赖于\b所特有的设备特定行为。

答案 1 :(得分:2)

这有点超出了C标准,因为它涉及输入/输出环境的行为,但通常退格字符只是重新定位光标。要备份和擦除,请尝试序列BACKSPACE SPACE BACKSPACE。

这是DEC VT100终端的行为,它非常普遍(也称为ANSI终端,XTERM派生终端使用相同的终端)。正如@jxh指出的那样,只有当输出设备是终端时才添加特定于终端的序列。如果您正在写入文件,则不会擦除,而只是将这些附加字节添加到输出流中。但是,如果稍后写入终端,可能仍然会使用cat正确解释这些延迟的序列。您可以使用POSIX函数isatty(3)来判断这些序列是否会被解释。

通过调整文件位置,可以在缓冲写入中取消字符。

FILE *myfile = /*initialization*/;
/* ... */
fsetpos (myfile, -1, SEEK_CUR);

还请考虑MvG对这些方法可能失败的更多方式的宝贵意见。 (它确实是一个不稳定的领域,超出标准.brrrrr。:)

答案 2 :(得分:1)

转义码“\ b”发出终端控制字符;也就是说,它将一个额外的控制字符写入输出流,它不会从输出流中删除以前的字符:在大多数系统中,“hellO \ bo”产生一个8字节的字符串文字,相当于{ 'h', 'e', 'l', 'l', 'O', '\b', 'o', '\0' };

但重要的是要记住这是一个终端控制角色。它的作用是终端相关的:一些终端移动光标左移停在第0列,一些移动光标向左移动包裹,一些擦除光标到达的字符,其他没有。

但更重要的是,如果您正在通过终端查看数据,那么它只是一个字节。例如。代码

#include <stdio.h>
int main(int argc, char* argv[]) {
    printf("Hello!\b\n");
}

将生成一系列ascii值,如果使用linux查看“cat”可能会显示“Hello”,使用Windows / DOS“more”命令,“Hello!” (DOS是一个非破坏性的退格键),如果在记事本中加载产生“你好!”接着是看起来像翼叮当的东西。

不要将终端控制与io-stream控制混淆。