Tag: buffer

为什么getch()没有读取输入的最后一个字符?

我正在使用ncurses库在C中编写一个蛇游戏,其中屏幕每秒更新一次。 当玩游戏的人知道,如果用户输入各种键或长按键,则不应存储“缓冲”按键。 换句话说,如果我按住w (向上键)并且stdin接收到20 w s的序列,然后输入d (右键),我希望蛇立即向右移动,并忽略缓冲w s。 我试图使用ncurses函数getch()实现这一点,但由于某种原因,我实现了我刚才描述的不良效果; 即在考虑最后一个按键之前,首先存储和处理任何长按键,因为这个MWE将说明: #include #include #include int main(){ char c = ‘a’; initscr(); cbreak(); noecho(); for(;;){ fflush(stdin); timeout(500); c = getch(); sleep(1); printw(“%c”, c); } return 0; } 有没有什么办法可以修改这段代码,以便getch()忽略任何缓冲的文本? 之前的fflush()似乎没有帮助。

C在提交之前读取stdin缓冲区

很可能这种情况是不可能的,因为我没有发现这种行为记录在任何地方,但很奇怪,如果有人有任何技巧来完成这样的事情。 在用户实际点击enter以提交数据之前,是否可以确定程序的stdin缓冲区的内容? 我正在尝试这样做,因为我已经构建了一个简单的终端聊天程序,它将消息从一个终端发送到另一个终端以便于通信。 我们遇到的问题是,由于传入的消息和传出消息一起出现在终端中,如果用户在从另一端收到消息时键入消息,则会扭曲显示并在新的结尾处附加键入的消息收到消息。 如果有办法检查缓冲区的内容并采取相应的行动会很方便,但我不确定如果没有gui类型的接口级别,这是否可行。

ReadFile和Overlapped出错

我有ReadFile和重叠的问题。 首先我使用与0重叠的ReadFile ZeroMemory(&overlapped ,sizeof(OVERLAPPED)); hDevice = CreateFileW(zwpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if(hDevice != INVALID_HANDLE_VALUE){ ret = ReadFile(hDevice, buff, 1024, &numerobyte, &overlapped); } 使用for(),我可以使用printf()查看字节 for (int n=0; n<sizeof(buff); n++) { printf("0x%02X ", buff[n]); } 现在我有一个大数字的变种 crbig = 322122547 d1 = (DWORD*)crbig; overlapped.Offset = d1[1]; //22122547 overlapped.OffsetHigh = d1[0];// […]

使用接近`INT_MAX`的`count`值来传递数据

消息传递接口API始终使用int作为count变量的类型。 例如, MPI_Send的原型是: int MPI_Send(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm); 如果要发送或接收的元素数量增长接近或甚至超过 INT_MAX则这可能是一个问题。 当然,这个问题可以解决,通过以下方式降低count : 将单个呼叫分成多个呼叫 定义(不必要的)聚合MPI_Datatype 无论如何,这两种方法都不是真正的解决方案,特别是如果使用简单的启发式方法实现的话。 因此,我想问的是: 使用标准MPI呼叫处理这类案件是否有更好的习惯用法? 如果没有,是否有人知道围绕MPI构建的一些(可靠的)包装器库来克服这个限制?

为什么char name 可以容纳多个字符?

当我遇到这种情况时,我正在对一个主题进行一些研究。 假设以下C代码: #include int main() { char name[1]; scanf(“%s”,name); printf(“Hi %s”,name); return 0; } 我已经使用-fno-stack-protector进行了编译,并使用大于1的输入进行了测试,就像John一样,令我惊讶的是,它有效! 当输入长于1时,它不应该抛出分段错误吗? 最终它打破了Alexander作为输入(9),但它适用于任何小于9的东西。 为什么输入的时间长于名称数组长度? PS:我使用Ubuntu(64位),gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04)和CLion作为IDE。

scanf / getchar只在第一次循环时正常工作?

我试图让用户输入一个他们想要的次数(并为每个数字创建一个链表节点)。 但是,我尝试了多种清除字符输入缓冲区的方法,但无济于事。 奇怪的是,代码将执行一次但不能正确执行第二次。 例如,使用下面的代码,终端读取: would you like to enter an integer? y Enter an integer: 4 would you like to enter an integer? y **program terminates** 在我使用scanf(“%c”, yesno); 我甚至不能在最后一行输入’y’。 它刚刚终止。 struct node *read_numbers(void){ struct node *first = NULL; int n; char yesno; yesno = ‘y’; while( yesno == ‘y’){ printf(“Would you like enter an integer […]

scanf何时开始和停止扫描?

当按下Enter键时, scanf似乎开始扫描输入,我想用下面的代码validation这一点(为简单起见,我省略了错误检查和处理)。 #include int main(int argc, char **argv) { /* disable buffering */ setvbuf(stdin, NULL, _IONBF, 0); int number; scanf(“%d”, &number); printf(“number: %d\n”, number); return 0; } 这是另一个问题,在我禁用输入缓冲之后(只是为了validation结果;我知道我应该接下来 – 实际上从不这样做,以防它干扰结果),输出是(注意额外的提示): $ ./ionbf 12(space)(enter) number: 12 $ $ 这与输入缓冲启用时的输出不同(无额外提示): $ ./iofbf 12(space)(enter) number: 12 $ 启用缓冲区时似乎消耗了新行字符。 我在两台不同的机器上进行了测试,一台安装了gcc 4.1.2和bash 3.2.25,另一台安装了gcc 4.4.4和bash 4.1.5,结果两者相同。 问题是: 如何在启用和禁用输入缓冲时解释不同的行为? 回到原来的问题, scanf什么时候开始扫描用户输入? 角色进入的那一刻? […]

撤消ungetc()的效果:“如何”fseek(),rewind()和fsetpos()这样做?每次都重新填充缓冲区吗?

嗯!!我怎么能把整件事放在一个明确的问题上!!让我试试: 我知道使用fopen()打开的文件被缓冲到内存中。我们使用缓冲区来提高效率。在从文件中读取文件时,首先将文件内容读入缓冲区,然后从该缓冲区中读取。类似地,在对文件的写入中,首先将内容写入缓冲区,然后写入文件。 但是fseek() , fsetpos()和rewind() 丢弃之前调用ungetc()呢? 你能告诉我它是如何完成的吗?我的意思是,鉴于我们已经打开了一个文件进行读取并将其复制到缓冲区中。现在使用ungetc()我们已经更改了缓冲区中的一些字符。这就是我刚才失败的地方即使经过多方努力也能理解 以下是关于ungetc()说法 – “对fseek,fsetpos或fwindpos的调用会丢弃之前使用此函数重新放入其中的任何字符。” – 如何放弃已放入缓冲区的字符?一种方法是删除被删除的原始字符,并将每个放入的新字符识别并替换为原始字符。但这似乎效率很低。另一种选择是将原始文件的副本加载到缓冲区中,并将文件指针放在预期的位置。这两个方法的fseek,fsetpos或rewind采取放弃使用ungetc()放置的字符? 对于文本流,流中未读字符的存在,使用ungetc()放入的字符如何影响ftell()的返回值?我的混淆来自关于ftell()和ungetc()的以下行关于ftell这个链接( SOURCE ) “对于文本流,数值可能没有意义但仍然可以用于稍后使用fseek将位置恢复到相同位置( 如果使用ungetc放回的字符仍然等待被读取,则行为未定义 )。” 关注上段的最后一行, pending of being read与“ungetc() – 获得的”字符被丢弃有关吗? 每次我们读取使用ungetc()放入流中的ungetc() ,它是否在读取后被丢弃 ?

sprintf缓冲区大小

我是新手程序员,但通常我可以解开自己的问题。 这次我解决了这个问题,但它仍然让我感到困惑。 一位朋友建议我问这个社区的意见。 我正在尝试用C打印数字。我有一个使用sprintf执行此操作的function。 数字永远不应超过2位数,所以我使用2个字符的缓冲区。 不知何故,这是我的逻辑失败的原因,因为这会通过修改传递给sprintf的变量之一而导致无限循环,但增加缓冲区大小可以解决问题。 这是失败的代码: #include void printarray(int array[][4]) { int y; int z; char buf[2]; for (y=0; y<4; y++) { for (z=0; z<4; z++) { sprintf(buf, "%d", array[y][z]); printf("buf is %s, y is %d and z is %d\n",buf,y,z); } } } int main() { int arr[4][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0} }; printarray(arr); return […]

在C中动态指定scanf的最大字符串长度(如printf中的“%* s”)

我可以使用这种技术指定scanf读取buffer的最大字符数: char buffer[64]; /* Read one line of text to buffer. */ scanf(“%63[^\n]”, buffer); 但是如果我们在编写代码时不知道缓冲区长度怎么办? 如果它是函数的参数怎么办? void function(FILE *file, size_t n, char buffer[n]) { /* … */ fscanf(file, “%[^\n]”, buffer); /* WHAT NOW? */ } 此代码容易受到缓冲区溢出的影响,因为fscanf不知道缓冲区有多大。 我记得以前见过这个,并开始认为这是解决问题的方法: fscanf(file, “%*[^\n]”, n, buffer); 我的第一个想法是”%*[*^\n]”表示最大字符串大小传递参数(在本例中为n )。 这就是printf *的含义。 当我检查scanf的文档时,我发现它意味着scanf应该丢弃[^\n] 。 这让我有些失望,因为我认为能够为scanf动态传递缓冲区大小是一个非常有用的function。 有什么办法可以动态地将缓冲区大小传递给scanf吗?