1

我正在将大量 f77 程序移植到一个新系统,使用 gfortran 而不是 g77 进行编译。其中一些程序使用 Fortran 读取语句和(自定义)C 例程从标准输入读取。如果程序以交互方式运行,这可以正常工作,但如果交互式输入作为通过管道传输到程序的单独文件或作为此处文档提供,则不能。对于这最后两种情况,如果 Fortran 读取后跟 C getchar,则 getchar 返回 EOF 而不是文件的未读部分。

用对 fget 的调用替换 Fortran 读取可以解决管道输入的问题,但不能解决 here 文档的问题。

所有这些都使用 sh shell,在 Mac OS X 10.8.4 上;gfortran 是 gcc 4.6.2 而 gcc for C 是 Apple 版本 4.2.1(我确实打算使用一致的 gcc 重试此操作,但目前不能)。

有谁知道原因,或者解决方法?

这是一个创建和编译两个程序并演示问题的脚本:

#!/bin/sh
cat << XXX > tmp.f
character*1 sym,dum
call fget(sym)
write(6,*) sym
call tmpc
stop
end
XXX
cat << XXX > tmpc.c
#include <stdio.h>
#include <ctype.h>
float tmpc_()
{
int c;
      c=getchar();
      fprintf(stderr,"1. c is %o %d\n",c,c);
      c=getchar();
      fprintf(stderr,"2. c is %o %d\n",c,c);
      c=getchar();
      fprintf(stderr,"3. c is %o %d\n",c,c);
      fprintf(stderr,"\n");
return(0);   
}
XXX
gcc -c tmpc.c
gfortran tmp.f tmpc.o
cat << XXX > tmp
*
2.34 12
XXX
cat tmp | a.out
a.out << XXX
*
2.34 12
XXX
rm tmp.f a.out tmpc.c tmpc.o tmp

输出是(文件传输时的前四行,当它是 here 文档时的第二行):

 *
1. c is 12 10
2. c is 62 50
3. c is 56 46


 *
1. c is 37777777777 -1
2. c is 37777777777 -1
3. c is 37777777777 -1

第一组是正确的: c 的值对应于字符 \n 2 。正如他们应该的那样。

4

1 回答 1

1

IIRC g77 运行时 I/O 库是在 C stdio 之上实现的,而 GFortran I/O 库直接使用 POSIX I/O api 并进行自己的缓冲。因此,C 和 Fortran 缓冲区很可能不同步,从而出现问题。

此外,在某些 GFortran 版本中,在处理不可搜索的文件方面存在错误。

通常,避免对同一文件执行混合语言 I/O。不过,将 C 用于一个文件而将 Fortran 用于另一个文件是完全可以的。只是不要混合它们。

于 2013-07-30T08:07:01.120 回答