user-0 提问: 新手求大佬帮忙看看

回复:
user: user-0
content: 引用 10 楼 cfjtaishan 的回复:[quote=引用 9 楼 jtidni 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 7 楼 jtidni 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] #pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。 gets不安全么？什么意思？我看的书里没介绍fgets，不懂。 谢谢你的建议[/quote] gets是不判断你输入多少个字符到缓存str1里的，如果输入超过30，gets是不做任何处理的。 fgets会将超出的部分，截断，保证输入的数据不会越界。[/quote] 懂了，谢谢， 今天我也遇到了一个gets很奇怪的问题，能帮我看看么？谢谢了，不懂为什么会这样。 #pragma warning(disable:4996) #include<stdio.h> int main() { 	char str1[20], str2[20]; 	char*p1 = &str1[0], *p2 = &str2[0]; 	scanf("%s", str1); 	gets(str2); //这样写只能输入一次就输出了，改成scanf正常。单独用gets又正确。 	int x; 	int strcmp(char*x, char*y); 	x = strcmp(p1, p2); 	printf("%d\n", x); 	return 0; } int strcmp(char*p1, char*p2) { 	int i = 0; 	while (*(p1 + i) == *(p2 + i)) 	{ 		if (*(p1 + i) == '\0')return 0; 		i++; 	} 	return(*(p1 + i) - *(p2 + i)); }[/quote] 这是因为gets遇到回车就返回，这个回车是上面输入str1留在输入缓存里的，在scanf("%s", str1);后面加一句getchar();就可以，加这句的作用就是接收（吸收）上次输入残留在输入缓冲区里的回车符[/quote] 谢谢您了，

user: user-1
content: 引用 9 楼 jtidni 的回复:[quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 7 楼 jtidni 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] #pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。 gets不安全么？什么意思？我看的书里没介绍fgets，不懂。 谢谢你的建议[/quote] gets是不判断你输入多少个字符到缓存str1里的，如果输入超过30，gets是不做任何处理的。 fgets会将超出的部分，截断，保证输入的数据不会越界。[/quote] 懂了，谢谢， 今天我也遇到了一个gets很奇怪的问题，能帮我看看么？谢谢了，不懂为什么会这样。 #pragma warning(disable:4996) #include<stdio.h> int main() { 	char str1[20], str2[20]; 	char*p1 = &str1[0], *p2 = &str2[0]; 	scanf("%s", str1); 	gets(str2); //这样写只能输入一次就输出了，改成scanf正常。单独用gets又正确。 	int x; 	int strcmp(char*x, char*y); 	x = strcmp(p1, p2); 	printf("%d\n", x); 	return 0; } int strcmp(char*p1, char*p2) { 	int i = 0; 	while (*(p1 + i) == *(p2 + i)) 	{ 		if (*(p1 + i) == '\0')return 0; 		i++; 	} 	return(*(p1 + i) - *(p2 + i)); }[/quote] 这是因为gets遇到回车就返回，这个回车是上面输入str1留在输入缓存里的，在scanf("%s", str1);后面加一句getchar();就可以，加这句的作用就是接收（吸收）上次输入残留在输入缓冲区里的回车符

user: user-0
content: 引用 8 楼 cfjtaishan 的回复:[quote=引用 7 楼 jtidni 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] #pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。 gets不安全么？什么意思？我看的书里没介绍fgets，不懂。 谢谢你的建议[/quote] gets是不判断你输入多少个字符到缓存str1里的，如果输入超过30，gets是不做任何处理的。 fgets会将超出的部分，截断，保证输入的数据不会越界。[/quote] 懂了，谢谢， 今天我也遇到了一个gets很奇怪的问题，能帮我看看么？谢谢了，不懂为什么会这样。 #pragma warning(disable:4996) #include<stdio.h> int main() { 	char str1[20], str2[20]; 	char*p1 = &str1[0], *p2 = &str2[0]; 	scanf("%s", str1); 	gets(str2); //这样写只能输入一次就输出了，改成scanf正常。单独用gets又正确。 	int x; 	int strcmp(char*x, char*y); 	x = strcmp(p1, p2); 	printf("%d\n", x); 	return 0; } int strcmp(char*p1, char*p2) { 	int i = 0; 	while (*(p1 + i) == *(p2 + i)) 	{ 		if (*(p1 + i) == '\0')return 0; 		i++; 	} 	return(*(p1 + i) - *(p2 + i)); }

user: user-1
content: 引用 7 楼 jtidni 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] #pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。 gets不安全么？什么意思？我看的书里没介绍fgets，不懂。 谢谢你的建议[/quote] gets是不判断你输入多少个字符到缓存str1里的，如果输入超过30，gets是不做任何处理的。 fgets会将超出的部分，截断，保证输入的数据不会越界。

user: user-0
content: 引用 5 楼 cfjtaishan 的回复:#pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。 gets不安全么？什么意思？我看的书里没介绍fgets，不懂。 谢谢你的建议

user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 我刚学没多久，你说的那个单步调试和设断点调试，不会用==。 你说的是对的，可能当时确实脑子发热，憋了一下午都没看出来。 我会去试试你说的单步调试和断点调试的。 谢谢

user: user-1
content: #pragma warning(disable:4996) #include<stdio.h>  void str_c(char x[], char y[], int n); int main() {     char str1[30], str2[30];     int m;      printf("please enter string:");     fgets(str1, 30, stdin);     printf("which character that begin to copy?  ");     scanf("%d", &m);     str_c(str1, str2, m);     printf("%s\n", str2);     return 0; } void str_c(char x[], char y[], int n) {     int i;      for (i = n; x[i]; i++)             y[i - n] = x[i];     y[i - n] = '\0'; } 建议两点： 1. 函数声明放在main函数外，这样更符合代码规范； 2. 用fgets替换gets更安全。

user: user-2
content: x[i] != '\0';

user: user-3
content: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-0
content: 66666666，昨天还真憋了一下午，就没看到这个小细节。

user: user-4
content: for (i = n; i != '\0'; i++) //改为 for (i = n; x[i] != '\0'; i++)