【问题标题】:Behavior of fgetc() function in CC 中 fgetc() 函数的行为
【发布时间】:2016-04-16 05:10:14
【问题描述】:

我正在寻找一种简单的方法来管理 linux 上 x86-64 程序集中的文件打开和关闭。我认为最简单的方法是编写一个包含我可以调用而不必担心稳定性的函数的 c 文件。所以我写了这个函数:

struct PORT open_port(char *filename, int mode) {
   struct PORT port;
   port.p = 0;
   if (mode) {
   if (filename == "stdout")
     port.f = stdout;
   else
     port.f = fopen(filename, "wb+");
   } else {
   if (filename == "stdin")
      port.f = stdin;
  else 
     port.f = fopen(filename, "rb");
  }
  return port;
}

然后我像这样读取端口:

char readchar(struct PORT *port)
{
  char r;
  if ((*port).p)
    r = (*port).p;
  else 
    r = fgetc((*port).f);
  (*port).p = 0;
  return r;
}

其中PORT.p 是一个字符,其中包含当前位置的字符,PORT.f 是一个文件指针。然后我通过将参数放在%rdi%rsi 中,在我的汇编代码中调用这些函数。

当我读取普通文件时,一切都按预期工作,但 stdin 支持不起作用。我知道stdin 应该是值0,当我调试我的代码时,我可以看到保存文件指针的值确实是0,但是当代码到达fgetc() 调用时,它段错误。如果我在我的函数中简单地写fgetc(0);,也会出现分段错误。我不明白fgetc() 函数如何区分stdin 和普通0

如何使用这个(或非常相似的模式)阅读stdin?或者如果一切都错了,我应该怎么做才能在 x64 程序集中打开文件?关于它是如何工作的,我当然没有得到一些东西,我们将不胜感激。

(对于那些想知道这一切有什么意义的人:它能够读取下一个字符而不[在外观上]移动文件指针,所以有一个 peekchar 函数设置PORT.p,如果它未设置,所以p 可以保存该值直到它被读取)

【问题讨论】:

  • stdinFILE*,而不是整数文件描述符。所以它不是 0。
  • stdin的文件描述符可能是0,但stdinFILE *绝对不是0。另外,(*port).p的正确写法是port->p。跨度>
  • "想知道这一切有什么意义:" --> 要偷看,只需使用c=fgetc(f); ungetc(c,f);
  • 使用strcmp(filename, "stdout")==0 而不是filename == "stdout"

标签: c linux assembly fgetc


【解决方案1】:

这在用 C 编译时有效,但在汇编代码中无效,因为错误使用了 == 运算符。

由于 C 编译器只定义了字符串 "stdin" 一次,字符串指针相等,这使它看起来像它工作,但是当从汇编代码调用它时,指针发生了变化并且无法满足条件。

strcmp() 替换== 解决了它

【讨论】:

    猜你喜欢
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多