处理scanf和printf中的空格

时间:2022-09-05 22:22:35

I'm trying to come up with a C program that can accept whitespace in scanf and printf such as a first and last name, as part of a self-learning text I'm reading.

我正在尝试提出一个C程序,它可以接受scanf和printf中的空格,例如名字和姓氏,作为我正在阅读的自学文本的一部分。

I'm well-aware of buffer overflow potentiality and such security issues with these basic/old functions, but this is strictly for learning purposes, so I do need to stick to them.

我很清楚缓冲区溢出可能性以及这些基本/旧功能的安全问题,但这仅限于学习目的,因此我需要坚持使用它们。

My program looks like:

我的程序看起来像:

#include <stdio.h>
#include <conio.h>

int main(void)
{
    char name[30];

    printf("Type your name\n");

    scanf("%10[0-9a-zA-Z]", name);

    printf("%s\n", name);
    return 0;
}

and after compilation is able to read in the string with a whitespace, but I can only print the first chunk of text:

并且在编译之后能够用空格读入字符串,但我只能打印第一个文本块:

C:\Users\hackr>g++ -o whitespace.exe whitespace.c

C:\Users\hackr>whitespace.exe
Type your name
John Doe
John

C:\Users\hackr>

2 个解决方案

#1


scanf("%29[0-9a-zA-Z ]", name);
                    ^

You forgot to add a space to the accepted characters in your regex. Also, if your buffer is 30 bytes, you should accept 29 characters, not 10. Leave room for the NUL character.

您忘记在正则表达式中为可接受的字符添加空格。此外,如果您的缓冲区是30个字节,您应该接受29个字符,而不是10.为NUL字符留出空间。

Another thing to note is that the next time you read from stdin, it will read the characters in that line that weren't within the first 29 characters of that scanf before it begins reading the input from the next prompt. In order to fix that, add this after the scanf:

另外需要注意的是,下次从stdin读取时,它将读取该行中的字符,这些字符在开始从下一个提示读取输入之前不在该scanf的前29个字符内。为了解决这个问题,请在scanf之后添加:

while (getchar() != '\n')
    ; // read input to end of line

This will always work since '\n' is not in your accepted characters for the regex so it will be left in the stdin buffer.

这将始终有效,因为'\ n'不在正则表达式的可接受字符中,因此它将保留在stdin缓冲区中。

#2


Try this instead

试试这个

scanf("%29[^\n]", name);

This will read till a newline is encountered.

这将读取直到遇到换行符。

#1


scanf("%29[0-9a-zA-Z ]", name);
                    ^

You forgot to add a space to the accepted characters in your regex. Also, if your buffer is 30 bytes, you should accept 29 characters, not 10. Leave room for the NUL character.

您忘记在正则表达式中为可接受的字符添加空格。此外,如果您的缓冲区是30个字节,您应该接受29个字符,而不是10.为NUL字符留出空间。

Another thing to note is that the next time you read from stdin, it will read the characters in that line that weren't within the first 29 characters of that scanf before it begins reading the input from the next prompt. In order to fix that, add this after the scanf:

另外需要注意的是,下次从stdin读取时,它将读取该行中的字符,这些字符在开始从下一个提示读取输入之前不在该scanf的前29个字符内。为了解决这个问题,请在scanf之后添加:

while (getchar() != '\n')
    ; // read input to end of line

This will always work since '\n' is not in your accepted characters for the regex so it will be left in the stdin buffer.

这将始终有效,因为'\ n'不在正则表达式的可接受字符中,因此它将保留在stdin缓冲区中。

#2


Try this instead

试试这个

scanf("%29[^\n]", name);

This will read till a newline is encountered.

这将读取直到遇到换行符。