我实施ConcurrentDictionary<K,V>
,getchar()
有两个问题,当我使用BUFF_SIZE
时,1024
读取所有字符并返回一个字符丢弃其余的部分。这在循环中不起作用。
getchar()
当我将#ifndef BUFF_SIZE
#define BUFF_SIZE 1024
#endif
int my_getchar(void)
{
static char buff[BUFF_SIZE];
static char *chr;
int ret;
if ((ret = read(STDIN_FILENO, buff, BUFF_SIZE)) > 0)
{
chr = buff;
return (*chr);
}
return (EOF);
}
int get_line(char **line)
{
char *text = malloc(sizeof(char) * 4092);
int position = 0;
int c;
if (!text)
return (-1);
while (1)
{
c = my_getchar();
if (c == EOF || c == '\n')
{
text[position] = '\0';
*line = text;
return (1);
}
else
text[position] = c;
position++;
}
return (0);
}
设置为BUFF_SIZE
时,它在循环内工作正常,并且在循环外无法正常工作。我怎么解决这个问题?
1
答案 0 :(得分:0)
您的my_getchar()
跳过每个调用的BUF_SIZE - 1
个字符。每次调用它时 - 它会从BUF_SIZE
读取stdin
个字符(如果我们位于文件的末尾,则会更少)并返回第一个字符。所有其他都被删除了,因为当你下次再次调用它时它再次读取BUF_SIZE
个字符而不是从先前读取的缓冲区返回下一个字符。
答案 1 :(得分:0)
当你将BUFF_SIZE设置为1时,你正在调用这样的读取:
read(STDIN, buff, 1)
但是,由于STDIN连接到终端,因此允许read()在返回第一个字符之前等待输入一行。因此,该函数的行为正确(如所写)。
好消息是,如果你使用printf("%c\n", getchar());
,你会发现getchar()的行为方式相同。
您的版本的主要问题是它构建在read()
之上 - 真正的getchar()
位于<stdio.h>
,并且可以与使用中的调用混合FILE*
及其缓冲。因此,除非您重新实现所有stdio
,否则在其基元(例如fread
)上构建它可能是有意义的。
如果要重新实现所有<stdio>
,那么你应该实现一些等效于FILE
的缓冲区所在的位置(不在函数内部的静态变量中)。
答案 2 :(得分:0)
OP的代码读取BUFF_SIZE
char
s,仅返回1.
需要有选择地阅读。仅在以前的字符被填充时读取。
注意:最好将结构指针传递给状态(buff, index,count
),而不是使用static
变量,但要遵循OP的方法:< / p>
int my_getchar(void) {
static unsigned char buff[BUFF_SIZE];
static int index = 0;
static int count = 0;
if (index >= count) {
index = 0;
count = read(STDIN_FILENO, buff, BUFF_SIZE);
if (count == 0) return EOF; // end-of-file
if (count < 0) return EOF; // I/O error
}
return buff[index++];
}
注意:阅读unsigned char
缓冲区以区分EOF
和输入租船人非常重要。
根据STDIN_FILENO
属性,read()
的返回值0可能只是意味着输入目前不可用。然后使用
// count = read(STDIN_FILENO, buff, BUFF_SIZE);
// if (count == 0) return EOF; // end-of-file
do {
count = read(STDIN_FILENO, buff, BUFF_SIZE);
} while (count == 0);
答案 3 :(得分:-1)
您的my_getchar
功能存在问题。问题在这里:
/* When you do return *char only first char is returned */
if ((ret = read(STDIN_FILENO, buff, BUFF_SIZE)) > 0)
{
chr = buff;
return (*chr);
}
您正在执行return (*chr);
只返回char
中的第一个buff
,这样就不会返回\n
,因此您的get_line
是受影响因为它取决于\n
返回。这可以通过添加一个额外的静态变量来跟踪返回的最新char的位置来解决这个问题,如下所示。
int my_getchar(void)
{
static char buff[BUFF_SIZE];
static char *chr;
static int pos = 0; /* New static variable to track position */
static int ret = 0; /* Changed this to static */
if (pos >= ret) { /* if all data in buffer has been returned */
if ((ret = read(STDIN_FILENO, buff, BUFF_SIZE)) > 0)
{
chr = buff;
pos = 0;
return *(chr + pos++); /* return one char and update pos */
} else { /* if no more to read from stdin */
return EOF;
}
} else { /* if data still in buffer */
return *(chr + pos++); /* return one char and update pos */
}
}
现在,当my_getchar
到达缓冲区中\n
的邮件时,pos
将返回\n
,因此get_line
将在新版本之前获取所有字符线字符。
答案 4 :(得分:-2)
您的代码会尽可能多地读取字符:
read(STDIN_FILENO, buff, BUFF_SIZE)
最多BUFF_SIZE
,然后只返回第一个字符。
为了使其按预期工作,您的缓冲区大小必须为1。