首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gets的替代方案?

gets的替代方案?
EN

Stack Overflow用户
提问于 2017-04-03 06:26:24
回答 2查看 9.5K关注 0票数 4

我曾经使用gets,但后来我听说它被从c11中删除了,而且总体来说它非常危险。所以我做了一些搜索,发现可以使用fgets()来做同样的事情。

问题是,当我使用fgets()时,它似乎也复制了行的末尾,这最终生成了额外的不想要的行。

来向你展示我的意思:

代码语言:javascript
复制
//if I have 
char key[30];
fgets(key, sizeof(key), stdin);

//now if ender for instance: Doggo and do:
printf("The key is:%s|hozaah!\n", key);

//I expect it to print:
The key is:Doggo|hozaah!

//Instead it prints:
The key is:Doggo
|hozaah!

有没有办法绕过这个问题?或者有没有其他函数可以代替我使用?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-03 07:18:03

没有标准的直接替代gets(),但是有很多简单的方法可以去掉换行符:

  • 最简单的使用strcspn (在<string.h>中声明):

if (fgets(buf,sizeof buf,fp)) { bufstrcspn(buf,"\n") = '\0';}

  • The classic using strlen

if (fgets(buf,sizeof buf,fp)) { size_t len = strlen(buf);if (len >0 && buflen '\n') buf--len = '\0';}

  • Another classic with strchr

if (fgets(buf,sizeof buf,fp)) { char *p = strchr(buf,'\n');if (p != NULL) *p = '\0';}

另一种方法是POSIX函数getline(),它可能在您的系统上可用:

代码语言:javascript
复制
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);

使用malloc()分配或重新分配缓冲区,并将其大小更新为*n。初始值应为lineptr = NULLn = 0

票数 4
EN

Stack Overflow用户

发布于 2017-04-03 07:04:48

答案在于这样一个事实:fgets读取缓冲区中可以容纳的尽可能多的字符,包括空终止符,但只读到文件末尾或换行符,并且它也会将换行符存储在字符串中:man 3 fgets

因此,如果您在终端上输入输入,换行符也会传输到标准输入,并由fgets读取。这不同于旧的gets,它用空字节替换换行符。

因此,如果您正在阅读行,并且不想要潜在的换行符,请将其去掉。不幸的是,fgets不会告诉您读取了多少个字符,因此您必须再次扫描字符串才能计算出来:

代码语言:javascript
复制
char* p = fgets(key, sizeof(key), stdin);

if (!p) { /* error */ }

size_t n = strlen(key);

if (n > 0 && key[n - 1] == '\n') {
  key[n - 1] = '\0';
} else {
  /* buffer too short or EOF reached without newline */
}

printf("The line was: '%s'\n", key);

可能值得考虑其他选择:如果只需要一个输入,不要一开始就输入换行符。如果需要很多行,可以在固定大小的缓冲区中使用fread,自己扫描新行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43174201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档