[英]Output the decimal versions of unknown input
我正在尝试编写一个简短的脚本,以接受将以十进制,十六进制或八进制表示的6个输入,并输出其十进制版本。 例如,如果我输入1,则应输出1。 输入010,应该为8,输入0x20,应该为32。我是否必须测试每个值以查看scanf是否将其读取为类型,或者我可以在scanf完全读取所有值后强制转换它们? 另外,我是否需要将八进制和十六进制值转换为十进制的函数,还是可以强制转换? 我是C语言的新手,现在还不太了解它,但这是我到目前为止的内容(无论出于何种原因,它输出-200到32765):
int num[6];
printf("Enter six integers:\n");
int i = 0;
int j;
while (i < 6){
if(scanf("0x%x", &j) == 1){
scanf("0x%x", &num[i]);
//hexToDec(num[i]);
} else if (scanf("0%o", &j) == 1){
scanf("0%o", &num[i]);
//octalToDec(num[i]);
} else {
scanf("%i", &num[i]);
}
i+=1;
}
for(int p = 0; p < 6; p+=1){
printf("%i\n", num[p]);
}
供将来参考:只需用“%i”扫描即可自动进行转换。 修改后的代码如下:
int main(){
int num[6];
printf("Enter six integers:\n");
int i = 0;
while (i < 6){
scanf("%i", &num[i]);
i+=1;
}
for(int p = 0; p < 6; p+=1){
printf("%i\n", num[p]);
}
}
您不能使用scanf("0x%x", &j)
测试输入,然后使用scanf("0x%x", &num[i])
将值放入num[i]
。 scanf
消耗它接受字符,因此它们是在输入流中不再。 当您执行第二次scanf
,字符消失了。
而是尝试扫描所需的东西。 如果有效,则完成。 如果不起作用,请继续执行else
:
if (scanf("0x%x", &num[i]) == 1)
; // Worked, nothing to do.
else if (scanf("0%o", &num[i]) == 1)
;
else if (scanf("%i", &num[i]) == 1)
;
else
{
// Nothing worked, should put error-handling code here.
}
对于实际的应用程序,这实际上并不是很好的代码,因为scanf
即使最终失败也会消耗一些输入。 例如,使用scanf("0x%x", &num[i])
,如果输入包含“ 0x”但随后包含非十六进制字符,则scanf
将使用“ 0x”,但保留下一个字符。 但是,这足以进行学习。
一旦您在num
数组中有了值,它们就是int
值。 它们是数学值,而不是八进制,十进制或十六进制的数字。 您可以使用%o
表示八进制,或者使用%d
或%i
表示十进制。 原始数字无关紧要。 打印时,数学值将用于以请求的基数格式化字符串。
您不应该使用%x
来打印int
,因为%x
是unsigned int
。 但是,您可以将int
转换为unsigned int
,然后使用%x
进行打印。
请注意,您不应使用%x
扫描到int
对象。 %x
用于扫描到unsigned int
对象。 您实际上可以使用以下方法扫描十六进制,八进制和十进制:
if (scanf("%i", &num[i]) == 1)
;
else
…
%i
规范将识别以“ 0x”开头的十六进制数字,以“ 0”开头的八进制数字和十进制数字。
如果您不想同时使用%i
,则由于某种原因要直接控制,则需要编写更多代码。 标准C没有提供将十六进制数字仅扫描到int
的直接方法。 您将需要从输入中获取字符并从中计算出它们的值,或者扫描到一个unsigned int
,然后将结果转换为int
。
您可以使用基数为0
strtol
根据输入字符串格式自动检测整数值的基数(例如,参见cppreference.com的strtol文档):
long strtol(const char * str,char ** str_end,int base)
解释str指向的字节字符串中的整数值。 ...有效的整数值由以下部分组成:
- (可选)加号或减号
- (可选)前缀(0)表示八进制基数(仅在基数为8或``0''时适用)
- (可选)前缀(0x或0X)表示十六进制的基数(仅在基数为16或``0''时适用)
如果base的值是``0'',则会自动检测数字底数。
因此,像long val = strtol("0x10",NULL,0);
这样的调用 将产生十进制值16。
请注意,您还可以将scanf
与格式说明符%i
结合使用,因为这被定义为与对strtol
的调用相同:
int scanf(const char * format,...)
%i匹配一个整数。 该数字的格式与strtol()所期望的相同,且base参数的值为``0''(base由解析的第一个字符确定)
快速答案是仅使用
if(scanf("%i", &j) == 1){
...
}
我到目前为止所拥有的(无论出于何种原因,它输出-200为32765):
然而, scanf()
错误处理很麻烦。 最好使用fgets()
读取用户输入的行 ,然后解析该行-也许使用strtol()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.