我想用 C 语言制作自己的 getline() 之类的函数,这就是我的想法:
void getstring(char *string)
{
fgets(string,STRING_LENGTH,stdin);
string[strlen(string)-1]='\0';
}
如果输入的字符数不超过 STRING_LENGHT(在本例中为 100)就足够了,但一旦超过,其上方的所有内容都会保留在缓冲区中并跳转到下一个读取的字符串。
我已经尝试使用以下过程刷新缓冲区:
void flush_buffer()
{
char c;
while((c = getchar()) != '\n' && c != EOF)
/* discard */ ;
}
它在所描述的情况下完成其工作,但一旦字符串不超过 STRING_LENGHT,我需要在继续之前输入任何内容。
有没有办法读取字符串,以便我知道是否超出 STRING_LENGHT,以便我可以调节刷新?
如果有更好的方法来实现 getline() 之类的函数,那就更好了。
最佳答案
Is there any way to read string such that I know whether STRING_LENGHT is exceeded or not so I can condition the flushing?
fgets()
读取的字符量不会达到或超过 STRING_LENGHT
。
但是要查明是否有更多行未读,通常的方法是检测读取的字符串是否具有最大长度并且不包含 '\n
'。
// return EOF, 0 (not all line was read) or 1 (all the line was read)
int getstring(char *string) {
if (fgets(string,STRING_LENGTH,stdin) == NULL) {
return EOF;
}
int retval = 1;
size_t sz = strlen(string);
if (sz + 1 == STRING_LENGTH && string[sz-1] != '\n') {
int c;
while((c = getchar()) != '\n' && c != EOF) {
retval = 0;
}
}
return retval;
}
<小时/>
传入大小更加稳健
// int getstring(char *string) {
// if (fgets(string,STRING_LENGTH,stdin) == NULL) {
int getstring(char *string, int sz) {
if (fgets(string,sz,stdin) == NULL) {
但要与 getline()
相同,还需要进行更多更改。 @Barmar
OP 的 flush_buffer()
当 char 是无符号且文件结尾为 true 时是一个无限循环。使用int
void flush_buffer(void) {
// char c;
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard */ ;
}
<小时/>
如果 fgets()
读取的第一个字符为空,string[strlen(string)-1]='\0';
是未定义行为 (UB)性格 - 一个值得避免的小漏洞。
fgets(string,STRING_LENGTH,stdin);
if (*string) {
string[strlen(string)-1]='\0';
}
另请参阅Removing trailing newline character from fgets() input .
关于c - 用 C 语言制作 getline(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54162158/