fgetc()函数在C中的行为

时间:2016-04-16 05:10:14

标签: c linux assembly fgetc

我正在寻找一种简单的方法来管理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可以保留值,直到读取为止)

1 个答案:

答案 0 :(得分:2)

这在使用C编译时有效,但由于==运算符的错误使用而无法使用汇编代码。

由于C编译器只定义了一次字符串"stdin",所以字符串指针相等使得它看起来像是有效的,但是当从汇编代码调用它时指针改变了,条件也不能得到满足。

==替换strcmp()解决了它