格式说明符“%02x”和“%3o”在此代码中的作用是什么?
What does the format specifiers "%02x " and "%3o " do in this code?
在搜索 K&R C 练习 7-2 语句的含义时,我在 https://clc-wiki.net/wiki/K%26R2_solutions:Chapter_7:Exercise_2
上找到了 K&R C 练习 7.2 的答案
练习要求
Write a program that will print arbitrary input in a sensible way. As a minimum, it should print non-graphic characters in octal or hexadecimal according to local custom, and break long text lines.
我也无法理解练习句的意思,特别是"As a minimum, it should print non-graphic characters in octal or hexadecimal according to local custom"部分。
练习 7-2 要求什么?请解释一下运动语句的含义。
下面的代码在代码末尾使用了格式说明符“%02x”和“%3o”来打印不可打印的字符,但是这些格式说明符对不可打印字符到底做了什么?
else
{
if(textrun > 0 || binaryrun + width >= split)
{
printf("\nBinary stream: ");
textrun = 0;
binaryrun = 15;
}
printf(format, ch);
binaryrun += width;
}
其余代码将长行分成较小的行,并按原样打印所有可打印字符。
完整程序如下:
#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] != '[=11=]')
{
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;
}
您已经自己找到“%02x”和“%03o”的意思了。太好了!
所以你的问题归结为 "What are non-printable characters?" 和 "How are they printed with the mentioned formats?"
不可打印字符由函数 can_print()
中的字符串 printable
定义(在显示的源代码中)。不在此字符串中的所有字符都被故意定义为不可打印。 我们可以对选择进行推理,但这超出了这里的范围。另一个注意事项:“”和“\t\f\v\r\n”在这组可打印字符中,并且在 ASCII 中的值 <= 0x20。
顺便说一句,标准库有 isprint()
检查可打印性。
正如您所知,每个字符都被编码为分配的值。这个值可以按照你喜欢的方式解释,作为一个字符,作为一个数字,作为一个指令,作为一种颜色,作为一个位模式,任何东西。实际上所有的数字计算机都只是在处理位模式,这取决于对它们的含义的解释。
所以一个不可打印的字符可以被解释为一个 int
数字,这就是 printf()
在提到的格式中发生的情况。假设读取的字符是“\b”,称为退格键。 (注:printable
中没有。) 在ASCII中这个字符被编码为0x08。所以输出将分别为“08”和“010”。
您可能希望以 所有 个字符被视为不可打印的方式更改程序。然后你会看到所有字符输出为十六进制或八进制。
在搜索 K&R C 练习 7-2 语句的含义时,我在 https://clc-wiki.net/wiki/K%26R2_solutions:Chapter_7:Exercise_2
上找到了 K&R C 练习 7.2 的答案练习要求
Write a program that will print arbitrary input in a sensible way. As a minimum, it should print non-graphic characters in octal or hexadecimal according to local custom, and break long text lines.
我也无法理解练习句的意思,特别是"As a minimum, it should print non-graphic characters in octal or hexadecimal according to local custom"部分。
练习 7-2 要求什么?请解释一下运动语句的含义。
下面的代码在代码末尾使用了格式说明符“%02x”和“%3o”来打印不可打印的字符,但是这些格式说明符对不可打印字符到底做了什么?
else
{
if(textrun > 0 || binaryrun + width >= split)
{
printf("\nBinary stream: ");
textrun = 0;
binaryrun = 15;
}
printf(format, ch);
binaryrun += width;
}
其余代码将长行分成较小的行,并按原样打印所有可打印字符。
完整程序如下:
#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] != '[=11=]')
{
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;
}
您已经自己找到“%02x”和“%03o”的意思了。太好了!
所以你的问题归结为 "What are non-printable characters?" 和 "How are they printed with the mentioned formats?"
不可打印字符由函数 can_print()
中的字符串 printable
定义(在显示的源代码中)。不在此字符串中的所有字符都被故意定义为不可打印。 我们可以对选择进行推理,但这超出了这里的范围。另一个注意事项:“”和“\t\f\v\r\n”在这组可打印字符中,并且在 ASCII 中的值 <= 0x20。
顺便说一句,标准库有 isprint()
检查可打印性。
正如您所知,每个字符都被编码为分配的值。这个值可以按照你喜欢的方式解释,作为一个字符,作为一个数字,作为一个指令,作为一种颜色,作为一个位模式,任何东西。实际上所有的数字计算机都只是在处理位模式,这取决于对它们的含义的解释。
所以一个不可打印的字符可以被解释为一个 int
数字,这就是 printf()
在提到的格式中发生的情况。假设读取的字符是“\b”,称为退格键。 (注:printable
中没有。) 在ASCII中这个字符被编码为0x08。所以输出将分别为“08”和“010”。
您可能希望以 所有 个字符被视为不可打印的方式更改程序。然后你会看到所有字符输出为十六进制或八进制。