scanf("%[^\n],str);和gets(str)

首先,调试环境是VS2017,所以没有gets只有gets_s,所以就只读入一个100个字符的字符串试试吧。

背景

这个问题产生的背景是这样的。我在PTA上刷题的时候产生了一些奇怪的现象,在开始我是以为scanf[]和gets是一样的,后来…我发现事情貌似并不是那么的简单…
题目描述:

scanf("%[^\n],str);和gets(str)

提交代码为

#include <stdio.h>
#include <string.h>
int main() {
	char str[81] = {};
	char c;
	int num[127] = {};
	scanf("%[^\n]\n%c", str, &c);
	int n = strlen(str);
	int i;
	for (i = 0; i < n; i++) num[str[i]]++;
	printf("%d", num[c]);
}

时的结果为

scanf("%[^\n],str);和gets(str)

有一个是不通过的,然后提交代码变为下面的时候是通过的

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
//#define gets(A) gets_s(A,81)
int main() {
	char str[81] = {};
	int num[127] = {};
	gets(str);
	char c = getchar();
	int n = strlen(str);
	int i;
	for (i = 0; i < n; i++) num[str[i]]++;
	printf("%d", num[c]);
}

scanf("%[^\n],str);和gets(str)

这是为什么呢?我进行了下面的实验。

测试用的代码如下:

#include <stdio.h>
#include <string.h>
#define gets(A) gets_s(A,100)
inline void input_str(char* str) {
	gets(str);
	scanf("%[^\n]",str);
}
int main() {
	char str[101] = {};
	input_str(str);
	printf("%s", str);
}



第一次,提交一个没有空格的字符串

gets的效果为:

scanf("%[^\n],str);和gets(str)

scanf的效果为:

scanf("%[^\n],str);和gets(str)




第二次,提交一个带有一个空格的字符串

gets的效果为:

scanf("%[^\n],str);和gets(str)

gets可以成功读入空格。

scanf的效果如下:

scanf("%[^\n],str);和gets(str)

也可以成功读取空格




第三次,提交一个带有一个制表符的字符串

gets的效果为:

scanf("%[^\n],str);和gets(str)

gets可以成功读取\t

那么,scanf呢?

scanf("%[^\n],str);和gets(str)

还是可以正确读取的。


所以…

第三次,组合攻击!!!!!!

gets的效果为:

scanf("%[^\n],str);和gets(str)

scanf的效果为:

scanf("%[^\n],str);和gets(str)

这他喵难道不一样吗?!?!

自闭了。

那就换个编译器试试?

VC6.0走起!

实验截图就省了吧,就上一张就可以说明问题了

scanf("%[^\n],str);和gets(str)

还是不能确定…

Dev-C试一下…

scanf("%[^\n],str);和gets(str)

so…是不是系统的问题?

那就换linux试一下吧。

系统:Ubuntu
编译器:GCC

现在GCC没gets,那就用fgets吧…

fgets和gets比会多吃一个回车

测试代码如下:

#include <stdio.h>
int main(){
    char str1[81] = {};
    char str2[81] = {};
    fgets(str1,81,stdin);
    scanf("%[^\n]",str2);
    getchar();
    printf("%s%s",str1,str2);
    getchar();
}

scanf("%[^\n],str);和gets(str)

好像也是没什么区别的吧…那么为什么不可以呢…有一些奇怪

用Kali试一下…

scanf("%[^\n],str);和gets(str)

结果也一样…

所以,两者应该没什么区别吧,大概…

所以,那个代码不可以是因为scanf读取c时的问题,把scanf换成getchar就好。