fgets 和 gets 的区别
Difference between fgets and gets
fgets()
和gets()
有什么区别?
我正在尝试在用户只点击 "enter" 时打破我的循环。它与 gets()
配合使用效果很好,但我不想使用 gets()
。
我尝试了 fgets()
和 scanf()
,但我没有得到与 gets()
相同的结果。 fgets()
打破循环,无论用户输入什么文本!这是我的代码:
void enter(void)
{
int i,
for(i=top; i<MAX; i++)
{
printf(".> Enter name (ENTER to quit): ");
gets(cat[i].name);
if(!*cat[i].name)
break;
printf(".> Enter Last Name: ");
scanf("%s",cat[i].lastname);
printf(".> Enter Phone Number: ");
scanf("%s",cat[i].phonenum);
printf(".> Enter e-Mail: ");
scanf("%s",cat[i].info.mail);
printf(".> Enter Address: ");
scanf("%s",cat[i].info.address);
printf("\n");
}
top = i;
}
gets 和 fgets 之间存在问题的区别在于,gets 会从输入行中删除尾随的“\n”,但 fgets 会保留它。
这意味着 fgets 返回的 'empty' 行实际上是字符串“\n”。
令人讨厌的区别,这意味着最好完全避免 gets,如果你给 gets 的一行太长,你的程序将以非常糟糕的方式崩溃。
gets()
和 fgets()
之间的区别是 fgets()
将换行符留在缓冲区中。因此,与其检查输入的第一个元素是否为 0
,不如检查它是否为 '\n'
;
fgets(cat[i].name, sizeof cat[i].name, stdin);
if (cat[i].name[0] == '\n' || cat[i].name[0] == 0) {
// empty line or no input at all
break;
} else {
// remove the trailing newline
int len = strlen(cat[i].name);
cat[i].name[len-1] = 0;
}
您可以将 fgets()
与 STDIN 一起使用。
这个函数是安全的,总是在字符串末尾插入一个'\0'。
一个例子:
char inputbuffer[10];
char *p;
p = fgets(inputbuffer, sizeof(inputbuffer), stdin);
printf(">%s<\n", p); /* p is NULL on error, but printf is fair */
在此示例中,您最多可以得到 9 个字符 + '\0'。
删除gets()
和scanf()
.
创建一个辅助函数来处理 和限定 用户输入。
// Helper function that strips off _potential_ \n
char *read1line(const char * prompt, char *dest, sizeof size) {
fputs(prompt, stdout);
char buf[100];
*dest = '[=10=]';
if (fgets(buf, sizeof buf, stdin) == NULL) {
return NULL; // EOF or I/O error
}
// Remove potential \n
size_t len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') {
buf[--len] = `[=10=]`;
}
// Line is empty or too long
if (len == 0 || len >= size) return NULL;
return memcpy(dest, buf, len+1);
}
void enter(void)
{
int i;
for(i=top; i<MAX; i++)
{
if (read1line(".> Enter name (ENTER to quit): ",
cat[i].name, sizeof cat[i].name) == NULL) break;
if (read1line(".> Enter Last Name: ",
cat[i].lastname, sizeof cat[i].lastname) == NULL) break;
if (read1line(".> Enter Phone Number: ",
cat[i].phonenum, sizeof cat[i].phonenum) == NULL) break;
if (read1line(".> Enter e-Mail: ",
cat[i].info.mail, sizeof cat[i].info.mail) == NULL) break;
if (read1line(".> Enter Address: ",
cat[i].info.address, sizeof cat[i].info.address) == NULL) break;
}
top = i;
}
fgets()
和gets()
的一些属性:
fgets()
读取输入并保存到缓冲区,直到:
1) 缓冲区差 1 满 - 或 -
2)遇到'\n'
-或-
3) 流达到文件结束条件 - 或 -
4) 发生输入错误。
gets()
执行上面的 #2 - #4 除了 它扫描,但不保存 '\n'
.
gets()
在 C99 中贬值,不再是 C11 的一部分。
fgets()
和gets()
有什么区别?
我正在尝试在用户只点击 "enter" 时打破我的循环。它与 gets()
配合使用效果很好,但我不想使用 gets()
。
我尝试了 fgets()
和 scanf()
,但我没有得到与 gets()
相同的结果。 fgets()
打破循环,无论用户输入什么文本!这是我的代码:
void enter(void)
{
int i,
for(i=top; i<MAX; i++)
{
printf(".> Enter name (ENTER to quit): ");
gets(cat[i].name);
if(!*cat[i].name)
break;
printf(".> Enter Last Name: ");
scanf("%s",cat[i].lastname);
printf(".> Enter Phone Number: ");
scanf("%s",cat[i].phonenum);
printf(".> Enter e-Mail: ");
scanf("%s",cat[i].info.mail);
printf(".> Enter Address: ");
scanf("%s",cat[i].info.address);
printf("\n");
}
top = i;
}
gets 和 fgets 之间存在问题的区别在于,gets 会从输入行中删除尾随的“\n”,但 fgets 会保留它。
这意味着 fgets 返回的 'empty' 行实际上是字符串“\n”。
令人讨厌的区别,这意味着最好完全避免 gets,如果你给 gets 的一行太长,你的程序将以非常糟糕的方式崩溃。
gets()
和 fgets()
之间的区别是 fgets()
将换行符留在缓冲区中。因此,与其检查输入的第一个元素是否为 0
,不如检查它是否为 '\n'
;
fgets(cat[i].name, sizeof cat[i].name, stdin);
if (cat[i].name[0] == '\n' || cat[i].name[0] == 0) {
// empty line or no input at all
break;
} else {
// remove the trailing newline
int len = strlen(cat[i].name);
cat[i].name[len-1] = 0;
}
您可以将 fgets()
与 STDIN 一起使用。
这个函数是安全的,总是在字符串末尾插入一个'\0'。
一个例子:
char inputbuffer[10];
char *p;
p = fgets(inputbuffer, sizeof(inputbuffer), stdin);
printf(">%s<\n", p); /* p is NULL on error, but printf is fair */
在此示例中,您最多可以得到 9 个字符 + '\0'。
删除gets()
和scanf()
.
创建一个辅助函数来处理 和限定 用户输入。
// Helper function that strips off _potential_ \n
char *read1line(const char * prompt, char *dest, sizeof size) {
fputs(prompt, stdout);
char buf[100];
*dest = '[=10=]';
if (fgets(buf, sizeof buf, stdin) == NULL) {
return NULL; // EOF or I/O error
}
// Remove potential \n
size_t len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') {
buf[--len] = `[=10=]`;
}
// Line is empty or too long
if (len == 0 || len >= size) return NULL;
return memcpy(dest, buf, len+1);
}
void enter(void)
{
int i;
for(i=top; i<MAX; i++)
{
if (read1line(".> Enter name (ENTER to quit): ",
cat[i].name, sizeof cat[i].name) == NULL) break;
if (read1line(".> Enter Last Name: ",
cat[i].lastname, sizeof cat[i].lastname) == NULL) break;
if (read1line(".> Enter Phone Number: ",
cat[i].phonenum, sizeof cat[i].phonenum) == NULL) break;
if (read1line(".> Enter e-Mail: ",
cat[i].info.mail, sizeof cat[i].info.mail) == NULL) break;
if (read1line(".> Enter Address: ",
cat[i].info.address, sizeof cat[i].info.address) == NULL) break;
}
top = i;
}
fgets()
和gets()
的一些属性:
fgets()
读取输入并保存到缓冲区,直到:
1) 缓冲区差 1 满 - 或 -
2)遇到'\n'
-或-
3) 流达到文件结束条件 - 或 -
4) 发生输入错误。
gets()
执行上面的 #2 - #4 除了 它扫描,但不保存 '\n'
.
gets()
在 C99 中贬值,不再是 C11 的一部分。