fgets不';扫描后不能工作 #包括 #包括 #包括 空数据空间(char*str); int main(){ int i,循环; 字符s1[101],s2[101]; scanf(“%d”、&loops); 而(循环--){ fgets(s1、101、stdin); fgets(s2、101、标准DIN); s1[strlen(s1)]='\0'; s2[strlen(s2)]='\0'; 如果(s1[0]='\n'&&s2[0]='\n'){ printf(“是\n”); 继续; } delspace(s1); delspace(s2); 对于(i=0;s1[i]!='\0';i++) s1[i]=tolower(s1[i]); 对于(i=0;s2[i]!='\0';i++) s2[i]=tolower(s2[i]); if(strcmp(s1,s2)==0){ printf(“是\n”); } 否则{ printf(“否”); } } 返回0; } void delspace(char*str){ int i=0; int j=0; 字符sTmp[strlen(str)]; while(str[i++]!='\0'){ 如果(str[i]!=''){ sTmp[j++]=str[i]; } } sTmp[j]='\0'; strcpy(str,sTmp); }
在我输入“循环”后,“s1”自动分配一个空行。这是怎么发生的?我确信我的键盘工作正常fgets不';扫描后不能工作 #包括 #包括 #包括 空数据空间(char*str); int main(){ int i,循环; 字符s1[101],s2[101]; scanf(“%d”、&loops); 而(循环--){ fgets(s1、101、stdin); fgets(s2、101、标准DIN); s1[strlen(s1)]='\0'; s2[strlen(s2)]='\0'; 如果(s1[0]='\n'&&s2[0]='\n'){ printf(“是\n”); 继续; } delspace(s1); delspace(s2); 对于(i=0;s1[i]!='\0';i++) s1[i]=tolower(s1[i]); 对于(i=0;s2[i]!='\0';i++) s2[i]=tolower(s2[i]); if(strcmp(s1,s2)==0){ printf(“是\n”); } 否则{ printf(“否”); } } 返回0; } void delspace(char*str){ int i=0; int j=0; 字符sTmp[strlen(str)]; while(str[i++]!='\0'){ 如果(str[i]!=''){ sTmp[j++]=str[i]; } } sTmp[j]='\0'; strcpy(str,sTmp); },c,scanf,fgets,C,Scanf,Fgets,在我输入“循环”后,“s1”自动分配一个空行。这是怎么发生的?我确信我的键盘工作正常 scanf()读取您要求它读取的内容,将以下\n从该行末尾保留在缓冲区中,fgets()将读取它。或者做一些事情来使用换行符,或者(我的首选解决方案)fgets(),然后从该字符串中sscanf()。scanf在输入缓冲区中保留空白,包括新行字符。要使用FGET读取下一行,需要手动删除当前行的其余部分: #include <stdio.h> #include <string.h> #in
scanf()
读取您要求它读取的内容,将以下\n
从该行末尾保留在缓冲区中,fgets()
将读取它。或者做一些事情来使用换行符,或者(我的首选解决方案)fgets()
,然后从该字符串中sscanf()
。scanf
在输入缓冲区中保留空白,包括新行字符。要使用FGET读取下一行,需要手动删除当前行的其余部分:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void delspace(char *str);
int main() {
int i, loops;
char s1[101], s2[101];
scanf("%d", &loops);
while (loops--) {
fgets(s1, 101, stdin);
fgets(s2, 101, stdin);
s1[strlen(s1)] = '\0';
s2[strlen(s2)] = '\0';
if (s1[0] == '\n' && s2[0] == '\n') {
printf("YES\n");
continue;
}
delspace(s1);
delspace(s2);
for (i = 0; s1[i] != '\0'; i++)
s1[i] = tolower(s1[i]);
for (i = 0; s2[i] != '\0'; i++)
s2[i] = tolower(s2[i]);
if (strcmp(s1, s2) == 0) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
void delspace(char* str) {
int i = 0;
int j = 0;
char sTmp[strlen(str)];
while (str[i++] != '\0') {
if (str[i] != ' ') {
sTmp[j++] = str[i];
}
}
sTmp[j] = '\0';
strcpy(str, sTmp);
}
瓦恩
Geekoaur已经很好地回答了您的问题,我只是指出了您的代码的另一个“问题”
行s1[strlen(s1)]='\0'
是一个ifs1
在执行前正确终止为空的函数
但是,如果s1
在执行这一行之前没有完全准备好并正确地以null结尾(您很不走运),它将导致:
- POSIX(*nix)系统上的
- 窗户上有一个窗户
strlen
basicali找到现有空终止符的索引并返回它!下面是一个有效的、未优化的strlen实现:
int c;
do{
c = getchar();
}while(c != EOF && c != '\n');
所以。。。如果您真的担心字符串不能以null结尾,那么您可以执行以下操作:
string[sizeof(string)]='\0'本地自动字符串上的代码>(其中编译器“知道”字符串的大小)李>
- 或
用于所有其他字符串,其中string[SIZE\u OF_string]
是(最常见的)一个SIZE\u OF_string
'd常量,或一个您专门维护的变量,用于存储动态分配字符串的当前大小(而不是长度)\define
- 或
- before:
memset(字符串,NULL,字符串的大小);
- 调用:
DirtyFunction(/*out*/string)
- 之后:
string[字符串的大小]='\0'
strncpy
并不总是空终止的……你可能是指strlcpy
。当6000万美元的账单运行崩溃时,我通过艰难的方式学会了这一点
编辑: 仅供参考:这里有一个“安全”(未优化)版本的strlen,我称之为
strnlen
(我想这应该在stdlib.Sigh中)
//重新计算字符串的长度(大小上限为-1)
int strnlen(字符*字符串,int大小){
int i=0;
虽然(我我知道这很旧。我是c新手,想检查我的方法,它使用getchar
:
// retuns the length of the string (capped at size-1)
int strnlen(char *string, int size) {
int i = 0;
while( i<size && string[i]!='\0' ) {
++i;
}
return i;
}
#包括
int main()
{
printf(“请输入您的姓名”);
字符串[10];
scanf(“%s”,字符串);
printf(“Hello%s\n”,字符串);
//getchar();#取消对这行的注释,fgets非常有效!!
printf(“请再次输入您的姓名\n”);
fgets(字符串,10,标准输入);
printf(“再次你好%s”,字符串);
getchar();
}
只要把
scanf(“%d\n”,&loops);
而不是
scanf(“%d”,&loops);
如果在使用scanf()后fgets()
被“跳过”,则以下操作有效
说完:
#include <stdio.h>
int main()
{
printf("Please enter your name\n");
char string[10];
scanf("%s", string);
printf("Hello %s\n", string);
//getchar(); # un commenting this line, fgets perfectly works!!
printf("Please enter your name again\n");
fgets ( string, 10, stdin );
printf("Hello again %s", string);
getchar();
}
说:
这将把输入缓冲区中剩余的任何内容存储到垃圾变量中
这将有效地清除输入缓冲区,并允许您在以后使用fgets()
编辑:
我最近了解到,有一个比上述更简单的解决方案。
如果在scanf()之后说getchar(),它将允许您毫无问题地使用fgets()。getchar()将获得输入缓冲区中的下一个字符,在本例中为“\n”。一旦从输入缓冲区中删除“\n”,fgets应该可以正常工作。这是一个更简单的解决方案
char garbage[100];
fgets(garbage,100,stdin);
扫描变量标签循环中的整数后,忽略以下换行符的另一种方法(由于按ENTER键)是:
scanf("%d",&loops);
while ((getchar()) != '\n'); //This will consume the '\n' char
//now you're free to use fgets
fgets(string,sizeof(string),stdin);
其中,根据手册页:
*禁止赋值。随后的转换将照常进行,但不使用指针;转换的结果将被丢弃
这是不太可能的,但是在测试过程中检查错误是一个好习惯
char garbage[100];
fgets(garbage,100,stdin);
scanf("%d",&loops);
while ((getchar()) != '\n'); //This will consume the '\n' char
//now you're free to use fgets
fgets(string,sizeof(string),stdin);
scanf ("%d%*c", &loops);
errno = 0
scanf ("%d%*c", &loops);
if (errno != 0) perror ("scanf");
// act accordingly to avoid un-necessary bug in the code
Enter in scanf: Hello
Enter in fgets:
Enter in scanf: Hello
Enter in fgets: Hello
Enter in fgets: Hello
Enter in scanf: Hello
Enter in scanf: Hello
Enter in fgets: Hello
Enter in sscanf: Hello
Enter in fgets: Hello