首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在这段代码中,格式说明符"%02x“和"%3o”做什么?

在这段代码中,格式说明符"%02x“和"%3o”做什么?
EN

Stack Overflow用户
提问于 2019-10-07 02:24:35
回答 1查看 760关注 0票数 0

在寻找K&R C练习7-2 I语句的意义时,这是对https://clc-wiki.net/wiki/K%26R2_solutions:Chapter_7:Exercise_2上K&R C练习7.2的回答。

这个练习要求

编写了一个程序,它将以合理的方式打印任意输入。作为最低限度,它应该打印八进制或十六进制的非图形字符根据当地的习惯,并打破长的文本行。

我也无法理解练习中句子的意思,特别是“至少要按照当地的习惯以八进制或十六进制打印非图形字符”。

这个练习7-2要求什么?请解释练习声明的含义。

下面的代码使用格式说明符"%02x“和"%3o”在代码末尾用来打印不可打印的字符,但是这种格式说明符对非打印机有什么作用呢?

代码语言:javascript
运行
复制
 else
    {
      if(textrun > 0 || binaryrun + width >= split)
      {
        printf("\nBinary stream: ");
        textrun = 0;
        binaryrun = 15;
      }
      printf(format, ch);
      binaryrun += width;
    }

其余代码将长行分解为较小的行,并打印所有可打印的字符。

完整的方案如下:

代码语言:javascript
运行
复制
    #include <stdio.h>

    #define OCTAL        8
    #define HEXADECIMAL 16


    void ProcessArgs(int argc, char *argv[], int *output)
    {
      int i = 0;
      while(argc > 1)
      {
        --argc;
        if(argv[argc][0] == '-')
        {
          i = 1;
          while(argv[argc][i] != '\0')
          {
            if(argv[argc][i] == 'o')
            {
              *output = OCTAL;
            }
            else if(argv[argc][i] == 'x')
            {
              *output = HEXADECIMAL;
            }
            else
            {
              /* Quietly ignore unknown switches, because we don't want to
              * interfere with the program's output. Later on in the
              * chapter, the delights of fprintf(stderr, "yadayadayada\n")
              * are revealed, just too late for this exercise.
              */
            }
          ++i;
          }
        }
      }
    }

    int can_print(int ch)
    {
      char *printable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 !\"#%&'()*+,-./:;<=>?[\\]^_{|}~\t\f\v\r\n";

      char *s;
      int found = 0;

      for(s = printable; !found && *s; s++)
      {
        if(*s == ch)
        {
          found = 1;
        }
      }

      return found;
    }

    int main(int argc, char *argv[])
    {
      int split = 80;
      int output = HEXADECIMAL;
      int ch;
      int textrun = 0;
      int binaryrun = 0;
      char *format;
      int width = 0;

      ProcessArgs(argc, argv, &output);

      if(output == HEXADECIMAL)
      {
        format = "%02X ";
        width = 4;
      }
      else
      {
        format = "%3o ";
        width = 4;
      }

      while((ch = getchar()) != EOF)
      {
        if(can_print(ch))
        {
          if(binaryrun > 0)
          {
            putchar('\n');
            binaryrun = 0;
            textrun = 0;
          }
          putchar(ch);
          ++textrun;
          if(ch == '\n')
          {
            textrun = 0;
          }

          if(textrun == split)
          {
            putchar('\n');
            textrun = 0;
          }
        }
        else
        {
          if(textrun > 0 || binaryrun + width >= split)
          {
            printf("\nBinary stream: ");
            textrun = 0;
            binaryrun = 15;
          }
          printf(format, ch);
          binaryrun += width;
        }
      }

      putchar('\n');

      return 0;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-07 08:34:08

你自己发现"%02x“和"%03o”是什么意思。那太好了!

所以你的问题归结为“什么是不可打印的字符?”以及“它们是如何用上述格式打印的?”

函数printable中的字符串can_print()定义了一个不可打印的字符(在源代码中)。所有不在此字符串中的字符都被故意定义为不可打印。我们可以对选择进行推理,但这超出了我们的范围。另一个注意事项:“”和"\t\f\v\r\n“位于这组可打印字符中,其值在ASCII中为<= 0x20。

顺便说一句,标准库有检查可打印性的isprint()

正如您似乎知道的那样,每个字符都被编码为赋值。这个值可以被解释成你喜欢的,一个字符,一个数字,一个指示,一个颜色,一个小图案,任何东西。实际上,所有的数字计算机都只是在研究位模式,这取决于它们的含义。

因此,一个不可打印的字符可以解释为一个int数字,这就是printf()使用上述格式所发生的事情。假设字符读为'\b',称为backspace。(注:不在printable__中。)在ASCII中,这个字符被编码为0x08。因此输出将分别为"08“和"010”。

您可能希望以这样的方式更改程序,即所有的字符都是不可打印的。然后,您将看到所有字符输出为十六进制或八进制。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58262817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档