简体   繁体   English

什么是 C 语言的 scanf("%*c") 的 C++ 等效项?

[英]What is the C++ equivalent of C language's scanf("%*c")?

Objective:客观的:

  • Simplest and similar way to discard any unwanted (which in my case is every non numeric characters but I'd like a solution for a more general case) and remove them from buffer .丢弃任何不需要的最简单和类似的方法(在我的情况下是每个非数字字符,但我想要一个更一般情况的解决方案)并将它们从 buffer 中删除 Example,例子,
#include<stdio.h>
void main(void){
    int num1, num2;
    
    printf("Enter num1 here : ");
    scanf("%d%*[^\n]%*c", &num);//First scanf statement.
    
    printf("Enter num2 here : ");
    scanf("%d", &num2);//Second scanf statement.
    
    printf("num1  is : %d\n
            num2 is : %d", num, num2);
}

    /* OUTPUT */
    1st number : 25 asdfasfasfasf
    2nd number : 30
    Input 1 : 25
    Input 2 : 30
    /* This will work by discarding any non */
    /* In the program above I didn't write a printf statment to display the text "1st num, 2nd num". This is just so the output is a bit more clear. I am aware of it.  */

Now if you change the first scanf from scanf("%d%[^\n]%*c");现在,如果您将第一个 scanf 从scanf("%d%[^\n]%*c"); to scanf("%d");scanf("%d"); and give the same input, you'd get the following output:并给出相同的输入,您将得到以下 output:

#include<stdio.h>

void main(void){
    int num1, num2;

    printf("Enter num1 here : ");
    scanf("%d", &num1);
    
    printf("Enter num2 here : ");
    scanf("%d", &num2);

    printf("num1 : %d\nnum2 : %d", num1, num2);
}
    //OUTPUT//
    Enter num1 here : 11 asdf
    Enter num2 here : num1 : 11
    num2 : 32764
   /*As you might see, I am not prompted for 2nd input. Instead the already present characters in the buffer are used.*/

Briefing:简报:

  • In C scanf("%d%[^\n]%*c");在 C scanf("%d%[^\n]%*c"); would remove all the redundant characters like spaces, newline, alphanumeric that come after the number form the buffer before/ after taking another input.将删除所有冗余字符,如空格、换行符、字母数字,这些字符在接受另一个输入之前/之后形成缓冲区的数字之后。 How can I achieve the same in C++ where after my cin >> var;我怎样才能在 C++ 在我的cin >> var; would take the remaining characters in the buffer and then discard them.将获取缓冲区中剩余的字符,然后丢弃它们。 This only works for numbers from 0-9.这仅适用于 0-9 的数字。 But what I am interested in is the *[^\n] and *c because it helps me read the characters from buffer without saving them anywhere which technically means that they get discarded.但我感兴趣的是*[^\n]*c因为它可以帮助我从缓冲区中读取字符而不将它们保存在任何地方,这在技术上意味着它们被丢弃。

Exclusions:排除:

  • cin >> ws;
  • cin.ignore(numeric_limits::max(),'\n');

I've found the aforementioned ways but unless there is no other more viable option available I'd rather not use these since it involves including external libraries #limits and #vector receptively.我已经找到了上述方法,但除非没有其他更可行的选择,否则我宁愿不使用这些方法,因为它涉及包含外部库#limits#vector接受。

In C scanf("%[^\n]%*c");在 C scanf("%[^\n]%*c"); would remove all the redundant characters like spaces, newline, alphaNumerics form the buffer before/ after taking another input.将在接受另一个输入之前/之后从缓冲区中删除所有冗余字符,如空格、换行符、alphaNumerics。

This is amiss in so many ways.这在很多方面都是错误的。

  1. "%[^\n]%*c" scans 1 or more non- '\n' (Attempting to save them) and then 1 '\n' . "%[^\n]%*c"扫描 1 个或多个非'\n' (尝试保存它们),然后扫描 1 个'\n' There must exist a leading non- '\n' else the scanning stops.必须存在一个前导非'\n'否则扫描停止。 There is nothing special about spaces and alphanumeric - just '\n' and non- '\n' .空格和字母数字没有什么特别之处 - 只是'\n'和非'\n'

  2. Undefined behavior : "%[^\n]" lacks a matching pointer to save the input.未定义的行为"%[^\n]"缺少用于保存输入的匹配指针。 Even with a matching char * , it lacks a width and is prone to buffer overflow.即使使用匹配的char * ,它也缺少宽度并且容易出现缓冲区溢出。 It is worse than gets() .它比gets()更糟糕。

  3. With an input of only "\n" , nothing is consumed, nothing is saved.仅输入"\n" ,不会消耗任何内容,也不会保存任何内容。 scanf("%[^\n]%*c"); fails to consume anything if the first character is a '\n' .如果第一个字符是'\n' ,则无法使用任何内容。 Without checking the return value, the calling code does not know if anything was read.如果不检查返回值,调用代码不知道是否读取了任何内容。 The matching char * , if it was there, is unchanged or potentially indeterminate.匹配的char * (如果存在)未更改或可能不确定。

Do not use scanf("%[^\n]%*c");不要使用scanf("%[^\n]%*c"); or its C++ equivalent std::scanf("%[^\n]%*c");或其 C++ 等效std::scanf("%[^\n]%*c");

Using C++20 onwards, you might want to use std::format .从 C++20 开始,您可能想要使用std::format This is basically an implementation of FMT into the standard C++.这基本上是在标准 C++ 中实现FMT

For more complex scenarios regular expressions should help.对于更复杂的场景,正则表达式应该会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM