【问题标题】:How do I seek in stdin我如何在标准输入中寻找
【发布时间】:2016-10-15 19:46:27
【问题描述】:

大家好,我需要帮助。我想从stdin 读取 16 个字节。我将每个字节转换为十六进制形式。有没有办法我可以使用read() 函数来读取不是从头开始,而是从第二个字节读取?另外我怎么知道我是否阅读了整个stdin? - 这样我可以循环调用这个函数,直到我读完整个stdin

这是我做的一个函数:

void getHexLine()
{

  int n = 16;
  char buffer[n];
  read(STDIN_FILENO, buffer, n);
  buffer[n]='\0';
  //printf("%08x", 0); hex number of first byte on line - not working yet
  putchar(' ');
  putchar(' ');
  //converting every byte into hexadecimal
  for (int i = 0;i < 16;i++ )
  {
    printf("%x", buffer[i]);
    putchar(' ');
    if (i == 7 || i == 15)
        putchar(' ');


  }
  printf("|%s|\n", buffer);
} 

输出应该是这样的,但可以选择从第二个字节开始。

[vcurda@localhost proj1]$ echo "Hello, world! This is my program." | ./proj1
48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 21 20 54 68  |Hello, world! Th|
69 73 20 69 73 20 6d 79  20 70 72 6f 67 72 61 6d  |is is my program|

这是一个学校项目,所以我不能使用mallocscanf&lt;string.h&gt;。如果我能得到一些帮助,我会非常高兴,并为我不太懂的英语感到抱歉。

【问题讨论】:

  • 你不能寻找字符流。其余的:太宽泛了。你应该学过功课。也许查阅您的课程资料会有所帮助。如果没有:有 C 本书可以免费访问。
  • buffer[n]='\0';
  • 您必须从read() 捕获返回值,这样您才能知道读取了多少字节,可以是0 (EOF) 到n(又名16)。您必须决定如何处理任何短读。

标签: c stdin


【解决方案1】:

stdin 不可搜索。您可以读取字节,但不能快退或快进。 EOF (-1) 表示标准输入中的输入结束,与常规文件一样,但如果您正在与用户进行交互式对话,则它的概念有点松散。

stdin 基本上是面向行的,最好使用模式 printf() 提示,从用户输入整行,printf() 结果(如果适用)和另一个提示,从用户读取整行等等,至少一开始,直到你习惯于编程标准输入。

从第二个字节开始就变得容易了。读入整行,然后在解析时从 i = 1 而不是 i = 0 开始。

【讨论】:

  • 如果流不可搜索,fseek 将返回 EBADF。否则它会做一些与搜索相对应的事情,但是如果你知道如何在标准输入上成功地做到这一点,你就会向stackoverflow发布一个不同类型的问题。
  • 如果 stdin 是重定向的常规文件,则搜索可能会成功。但假设 stdin 不可搜索可能总是好的。
  • 如果我运行一个程序./some_program &lt; plain_file,标准输入是可搜索的。如果您说“标准输入不一定是可搜索的”,那么就没有问题了——如果它是管道或终端,那么标准输入是不可搜索的。但一概而论是不正确的。
  • 计算机通常允许你在不同的组件之间放置不同的层,这会产生奇怪的效果。
  • 将“stdin 不可搜索”更改为“管道、套接字或终端不可搜索”。这种对标准输入的使用是完全可以寻找的:./proj1 &lt;myfile
【解决方案2】:

有没有办法可以使用 read() 函数从 开始,但例如从第二个字节开始?

大多数情况下,您可以简单地忽略您不感兴趣的读入字节。

有时您可以lseek,例如如果你运行你的程序 设置为其 STDIN 的常规文件,如下所示:

./a.out < /etc/passwd

lseek 将在终端、管道、字符设备或套接字的 STDIN 上失败。

我怎么知道我是否已经阅读了整个标准输入?

read 将在文件末尾返回 0


有关更多信息,请参阅手册页。 通常,您应该检查您的返回代码并考虑短读。您的函数可能应该返回一个 int,以便它能够传达可能的 IO 错误。

【讨论】:

  • 值得一提的是,./a.out &lt; /etc/passwd 很可能是由 Bash 使用 freopen 实现的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多