在scanf之后,fgets不起作用
#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); }
进入“循环”后,“s1”被自动分配一个空行。 这是怎么发生的? 我确定我的键盘工作正常。
scanf()
完全读取您要求的内容,在fgets()
将读取该行的缓冲区的末尾保留下列\n
。 要么做一些消耗新行,或者(我的首选解决scheme) fgets()
,然后sscanf()
从该string。
scanf
会在input缓冲区中留下空白,包括换行符。 要使用fgets读取下一行,您需要手动删除当前行的其余部分:
do{ int c = getchar(); }while(c != EOF && c != '\n');
Vayn,
Geekoaur已经很好的回答了你的问题,我只是用你的代码指出另一个“问题”。
行s1[strlen(s1)] = '\0';
如果s1
已经正确空终止,则在执行之前是空操作。
但是,如果s1
没有正确的空终止在此行执行(而你是不幸的),它会导致:
- 一个POSIX(* nix)系统上的SIGSEGV 。
- Windows上的GPF 。
这是因为strlen
basicalyfind现有的空终止符的索引并返回它! 这是strlen的一个有效的,未经优化的实现:
int strlen(char *string) { int i = 0; while(string[i] != '\0') { ++i; } return i; }
所以…如果你真的担心string不被空终止,那么你会做一些事情:
-
string[sizeof(string)]='\0';
在本地自动string(编译器“知道”string的大小); - 或
string[SIZE_OF_STRING]
,其中SIZE_OF_STRING
(最常见)是#define
的d常量,或者是专门用于存储dynamic分配string的当前大小(而非长度)的variables。
如果你是真的,真的,真的很担心string不被空终止(就像你正在处理“脏”的库方法(例如Tuxedo的ATMI),你也“清除”你的“返回string”,然后通过到疑似图书馆的方法有:
- 之前:
memset(string, NULL, SIZE_OF_STRING);
- invoke:
DirtyFunction(/*out*/string)
; - after:
string[SIZE_OF_STRING]='\0'
SIG11是一个完整的biatch,因为(除非你用信号处理器 “挂钩”它们,否则会导致unix硬性终止你的程序,所以你不能logging任何东西(事后),以帮助找出特别是考虑到在许多情况下,引发SIG11的代码行没有位于string的实际原因附近,从而失去了它的空终止符。
这对你有意义吗?
队友的欢呼声。 基思。
PS:警告: strncpy
不会allways nullterminate …你可能意味着strlcpy
。 我以艰难的方式了解到这一点…当6000万美元的计费运行崩溃。
编辑:
仅供参考:这里是strlen的“安全”(未优化)版本,我将称之为strnlen
(我认为这应该在stdlib中 。 strnlen
)。
// 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; }
我知道这是非常古老的。 我新来c,想检查我的方法,它使用getchar
:
#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(); }
只是把scanf("%d\n",&loops);
而不是scanf("%d",&loops);