来自stdin的read()不会忽略换行符

时间:2009-08-06 06:56:02

标签: c input newline stdin

我使用以下条件语句来读取标准输入。

if ((n = read(0,buf,sizeof(buf))) != 0)

从标准输入输入数据时,通常用户在完成后按Enter键。但read()也将'\ n'视为输入,在这种情况下n = 1并且条件不会计算为false。当用户在标准输入上按下enter(不输入任何内容)而不检查buf的内容时,是否有办法使条件计算为false。我可能会为此目的使用除read()以外的任何其他功能吗?

就此而言,当输入来自标准输入(stdin)时,读取什么方式可以确定输入结束?

5 个答案:

答案 0 :(得分:8)

你问:

  

从标准输入输入数据时,通常用户在完成后按Enter键。但read()也将'\ n'视为输入,在这种情况下n = 1且条件不会计算为false。

第一点肯定是正确的。 enter键等同于换行键,因此当用户按Enter键时,键盘会生成换行符,因此read()函数会返回该字符。它确实这样做至关重要。

因此,您的条件被误导 - 空行将包含换行符,因此字节计数将为1。实际上,当标准输入是键盘时,只有一种方法可以让read()调用返回0,这就是键入'EOF'字符 - 通常是Unix上的control-D,DOS上的control-Z。在Unix上,终端驱动程序将该字符解释为“即使没有换行符也将先前的输入数据发送到程序”。如果用户在该行上没有输入任何其他内容,则read()的返回值将为零。如果输入来自文件,则在读取最后一个数据后,后续读取将返回0个字节。

如果输入来自管道,则在读取管道中的所有数据之后,read()调用将阻塞,直到可写入管道的最后一个文件描述符关闭为止;如果该文件描述符在当前进程中,那么read()将永远挂起,即使挂起的进程永远不能write()到文件描述符 - 假设是单线程进程,当然

答案 1 :(得分:2)

只需输入>1而不是!=0

唯一的误报是单个字符响应,后跟中断(EOF)

答案 2 :(得分:1)

您必须自己检查缓冲区。 例如

while((n = read(0,buf,sizeof(buf))) > 0) {
  if(buf[0] == '\n') // won't handle pressing 9 spaces and then enter
    continue;
  ... process input

}

或使用例如fgets,然后剥离\ n

while(fgets(buf,sizeof buf,stdin) != NULL) {
  char *ptr;
  size_t len;

  if((ptr = strchr(buf,'\n')) != NULL) //strip newline
    *ptr = 0; 
  len = strlen(buf);
  if(len == 0)
   continue;
  ... process input 
}

答案 3 :(得分:0)

最好使用fgets()来完成任务(捕获用户输入),但即使fgets()也会在缓冲区中存储换行符。

但是如果有换行符,则可以确定它是字符串中的最后一个字符,因此很容易将其删除。

答案 4 :(得分:0)

我很肯定没有检查缓冲区内容就无法做到这一点。甚至readline()就是这么做的。无论如何,你为什么反对呢?