问题描述
char value1[10];
int value2;
int value3 = 0;
if (!scanf("%s %d %d", &value1[0], &value2, &value3)) {
scanf("%s %d", &value1[0], &value2);
}
;
我正在尝试使用 scanf
插入3个值,但是如果接收到2个值,它将取2个值.我找不到如何使用 scanf
的答案.我一直在尝试使用 fgets
,但stdin中的值仍然存在.
I am trying to use scanf
to insert 3 values, but if received 2 it will take in 2 instead. I'm not able to find any answer how to use scanf
. I've been trying to use fgets
but value in stdin remains.
推荐答案
scanf("%s %d %d", &value1[0], &value2, &value3)
问题是 scanf()
不能忽略第三个转换说明符.它仍然不断尝试捕获第三个参数 value3
的十进制输入.
The problem is scanf()
can´t ignore the third conversion specifier. It still keeps trying to catch the decimal input for the third argument, value3
.
首先捕获整个输入为字符串,然后再将该字符串的内容拆分为每个对象,可能是更好的选择.
To catching the whole input as string first and then later split the content of this string into each own object may be a better alternative.
fgets()
比 scanf()
更安全,所以我将使用 fgets()
./p>
fgets()
is a litte more safer than scanf()
when taking user input so I´ll use fgets()
.
char* fgets ( char * str, int num, FILE * stream );
使用 fgets()
,您需要定义要读取的字符数( num
),这是维护安全性的重要功能,但是在这种情况下,我们无需不知道用户可能会为十进制输入请求输入什么作为整数.如果我们为数字指定的字符较少,其余数字将保留在 stdin
中.
With fgets()
you need to define the amount of characters to read (num
), which is a great feature for maintaining security, but in this case we don´t know what a user potentially will input as integer for the decimal input requests. If we specify to less characters for the digits, the rest digits will be left in stdin
.
一种解决方法是指定对 fgets()
的调用中用十进制表示形式表示 int
类型整数的位数的总数.
A workaround would be to specify the total amount of digits possible for representing integers of type int
in decimal notation in the call to fgets()
.
在64位体系结构上,总数"2,147,483,647"将为10位,在32位体系结构上则为"32,767"总数的5位.我现在使用64位的情况.
These would be 10 digits for the total number of "2,147,483,647" on 64-bit architectures or 5 digits for the total number of "32,767" on 32-bit architectures. I go with the 64-bit case for now.
所以 10
(value1)+ 10
(value2)+ 10
(value3)+ 2
空格字符在value1和value2之间以及在value2和value3之间+字符串的终止 \ 0
= 33
个字符.请注意, fgets()
还会读取输入的换行符 \ n
(但稍后我们会轻松地从字符串中删除该换行符),因此我们甚至还需要一个字符.总共 34
个字符:
So 10
(value1) + 10
(value2) + 10
(value3) + 2
space characters between value1 and value2 and between value2 and value3 + the terminating \0
for a string = 33
characters. Note that fgets()
also reads the entered newline \n
(but we later discard that from the string easily) so we need even one character more; it is in total 34
characters:
char buffer[34];
fgets(buffer,sizeof(buffer),stdin);
此后,我们需要证明存储在 buffer
中的字符串中有多少内容.我们可以通过计算空格字符来隐式证明这一点:
After that we need to proof how many content we have in the string stored in buffer
. We can proof it implicitly by counting the space characters:
unsigned int mark;
for(unsigned int i = 0; i < (sizeof(buffer)/sizeof(buffer[0]) - 1)); i++)
{
if(buffer[i] == ' ')
mark++;
}
此后,我们需要使用 sscanf()
将 buffer
中的字符串内的各个内容片段传输/转换为适当的自己的对象.如果字符串中现在有2个空格字符,则可以在 sscanf
命令中使用3个转换说明符,否则我们有相应的 sscanf()
s:
Thereafter we need to transfer/convert the individual content pieces inside the string in buffer
to the appropriate own objects by using sscanf()
. If we now have 2 space characters in the string, we can use 3 conversion specifiers in a sscanf
command, else we have appropriate sscanf()
s:
if(mark == 2)
{
sscanf(buffer,"%s %d %d", value1, &value2, &value3);
}
else if(mark == 1)
{
sscanf(buffer,"%s %d", value1, &value2);
}
else if(mark == 0)
{
sscanf(buffer,"%s", value1);
}
else
{
printf("The input entered is not valid!\n");
printf("Please try again!\n");
}
那么整个代码就是:
#include <stdio.h>
#include <string.h>
int main()
{
char value1[10];
int value2;
int value3;
unsigned int mark;
char buffer[34];
for(;;)
{
fgets(buffer,sizeof(buffer),stdin);
buffer[strcspn(buffer, "\n")] = 0;
mark = 0;
for(unsigned int i = 0; i < ((sizeof(buffer)/sizeof(buffer[0]) - 1)); i++)
{
if(buffer[i] == ' ')
mark++;
}
if(mark == 2)
{
sscanf(buffer,"%s %d %d", value1, &value2, &value3);
break;
}
else if(mark == 1)
{
sscanf(buffer,"%s %d", value1, &value2);
break;
}
else if(mark == 0)
{
sscanf(buffer,"%s", value1);
break;
}
else
{
printf("The input entered is not valid!\n");
printf("Please try again!\n");
}
}
printf("value1 = %s\n", value1);
if(mark == 1 || mark == 2)
printf("value2 = %d\n", value2);
if(mark == 2)
printf("value3 = %d\n", value3);
return 0;
}
这篇关于如何使scanf选择性地忽略其转换说明符之一?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!