如何用Fortran将文件全部内容读取到预分配字符串中?
解决方案
问题出在使用列表导向的read(*)语句——它会在遇到空白或记录结束时停止读取,只能获取第一行内容。结合你使用的stream access模式,调整读取方式即可完整读取整个文件内容:
修改后的代码:
open (unit=11, status='scratch', access='stream', form='formatted') call jsonHandler%print(outputJson, 11) rewind(11) inquire(11, SIZE=file_size) ! 预分配与文件字节数匹配的字符串(ASCII编码下字符数=字节数) allocate(character(len=file_size)::output) ! Stream模式下直接读取全部字符到预分配字符串 read(11) output close(11)
关键说明:
- 去掉
read语句的格式说明符*,在stream access模式下,无格式的read(unit)会直接读取足够字符填满目标字符串,直到文件结束,忽略记录边界。 - 确保
inquire(SIZE=file_size)返回的是文件总字节数(大多数编译器对stream模式的scratch文件支持此查询),预分配的字符串长度与字节数匹配,保证能容纳所有内容。
如果遇到编译器对scratch文件SIZE查询不支持的情况,可改用循环读取拼接的方式(兼容性更强,效率略低):
open (unit=11, status='scratch', form='formatted') call jsonHandler%print(outputJson, 11) rewind(11) ! 先循环统计总字符数 integer :: io, file_size character(len=:), allocatable :: temp_str, output file_size = 0 do read(11, '(a)', iostat=io) temp_str if (io /= 0) exit file_size = file_size + len_trim(temp_str) + 1 ! 加1保留换行符 end do rewind(11) allocate(character(len=file_size)::output) output = '' do read(11, '(a)', iostat=io) temp_str if (io /= 0) exit output = trim(output) // temp_str // new_line('a') end do close(11)
内容的提问来源于stack exchange,提问作者Marty Farce
相关产品推荐
相关产品推荐

