|
本帖最后由 snljty 于 2020-12-22 00:25 编辑
更新:把python版本的测试代码也发上来了,编译python需要的pyd库的方法是使用numpy包的f2py模块。
- f2py -m read_double -c read_double.f90
复制代码
根据2L的回复,稍微改了一下,供参考。
假设要用C从input.txt里面读一行文本,然后从文本里读几个(Fortran格式的)双精度浮点数。
input.txt:
- 1.23 0.456E+01 0.789D+02 0.100+111
复制代码
test.c:- /**************************************************************
- * This file uses Fortran function read_double_from_string_ *
- **************************************************************/
- # ifdef __cplusplus
- extern "C" {
- # endif
- # include <stdio.h>
- # include <string.h>
- /* note */
- /* for most compilers, Fortran will append a '_' to the name of the function, */
- /* and uses only lower letters in name of functions. */
- /* also, please remember that Fortran passes addresses of arguments, but C/C++ passes values, */
- /* hence if you want to call a Fortran function in a C program, you have to pass pointers for all. */
- void read_double_from_string_(const int *const str_length, const char *const read_str, double *d_number);
- void read_fortran_double(const char *const read_str, double *d_number);
- int main()
- {
- const char splitter[] = " \r\n\t\v";
- FILE *ifp = fopen("input.txt", "rt");
- char buf[BUFSIZ + 1u] = "";
- double d = 0.0;
- char *tok = NULL;
- fgets(buf, BUFSIZ, ifp);
- tok = strtok(buf, splitter);
- while(tok)
- {
- read_fortran_double(tok, & d);
- /* sscanf(a, "%lf", & d); */
- printf("%g\n", d);
- tok = strtok(NULL, splitter);
- }
- fclose(ifp);
- ifp = NULL;
- return 0;
- }
- void read_fortran_double(const char *const read_str, double *d_number)
- {
- int len = (int)strlen(read_str);
- read_double_from_string_(& len, read_str, d_number);
- return;
- }
- # ifdef __cplusplus
- }
- # endif
复制代码
test.py:- #! /usr/bin/env python3
- # -*- Coding: UTF-8 -*-
- r"""
- This program uses fortran module read_double
- """
- import read_double
- with open('input.txt') as f:
- l = f.readline()
- read_fortran_double = lambda _: read_double.read_double_from_string(len(_), _)
- for s in l.strip().split():
- print(read_fortran_double(s))
复制代码
read_double.f90:
- ! this file reads a double from a string.
- subroutine read_double_from_string(str_length, read_str, d_number)
- implicit none
- integer(kind=4), intent(in) :: str_length
- character(len=str_length), intent(in) :: read_str
- real(kind=8), intent(out) :: d_number
- read(read_str, *) d_number
- return
- end subroutine read_double_from_string
复制代码
Makefile:- # Makefile for test
- CC = gcc
- FC = gfortran
- CLINKER = $(CC)
- FLINKER = $(FC)
- ARCH = ar
- all: test.exe
- test.exe: test.o static_lib
- # 可以用Fortran编译器链接
- $(FLINKER) -o $@ test.o -L . -l read_double
- # 也可以用C编译器链接,但是gcc默认是不链接libgfortran.*库的,可以加上-l gfortran
- # $(CLINKER) -o $@ test.o -L . -l read_double -l gfortran
- test.o: test.c
- $(CC) -o $@ -c $^
- read_double.o: read_double.f90
- $(FC) -o $@ $^
- static_lib: libread_double.a
- libread_double.a: read_double.o
- $(ARCH) -rsc $@ $^
- .PHONY: clean
- clean:
- -rm test.o read_double.o
- -rm test.exe
- -rm libread_double.a
复制代码
感觉这个方法很适合像我这样C写起来相对顺手,极度恐惧Fortran,超过5行Fortran写起来都难受的人...
|
评分 Rate
-
查看全部评分 View all ratings
|