Cỏc lệnh nhập, xuất dữ liệu với file

Một phần của tài liệu Ngôn ngữ lập trình Fortran và ứng dụng trong khí tượng thủy văn (Trang 53 - 59)

Để sử dụng cỏc file với chương trỡnh của mỡnh, chỳng ta phải dựng những lệnh mới để thao tỏc với file và những mở rộng đối với một số lệnh đó nghiờn cứu trong cỏc chương trước. Những lệnh này truy cập đến tờn file mà ta đó gỏn khi tạo lập file. Nếu ta tạo lập một file dữ liệu bằng phần mềm soạn thảo, ta gỏn tờn cho file khi nhập dữ liệu. Nếu ta tạo ra một file bằng một chương trỡnh, ta phải dựng một lệnh trong chương trỡnh cấp cho file một tờn nhất định.

Nếu một file chuẩn bị được dựng trong chương trỡnh, file đú phải được mở ra trước khi cú một thao tỏc nào đú với nú. Lệnh mở file OPEN bỏo cho chương trỡnh một số thụng tin cần thiết về file như tờn file, file đú

53

mở ra để đọc hay để ghi dữ liệu. Ngoài ra lệnh OPEN gắn file được mở với một số hiệu file để khi nào chương trỡnh truy cập file thỡ nú sử dụng số hiệu đú. Dạng tổng quỏt của lệnh OPEN mà ta sử dụng trong chương này như sau:

OPEN (UNIT =biểu thức nguyờn, FILE =tờn file, STATUS =văn bản) trong đú biểu thức nguyờn chỉ định một số hiệu thiết bị được gỏn cho file,

tờn file chỉ định một tờn mà ta đó gỏn cho file khi tạo lập ra nú và văn bản

STATUS bỏo cho chương trỡnh biết file mở ra để đọc hay để ghi, file đó tồn tại hay chuẩn bị tạo ra. Nếu là file để đọc, ta chỉ định

STATUS = 'OLD'

nếu file mở ra để xuất, ta chỉ định

STATUS = 'NEW'

cũn

STATUS = 'UNKNOWN'

cho phộp mở file mới hoặc ghi đố lờn file đó tồn tại.

Lệnh OPEN phải đứng trờn những lệnh READ hoặc WRITE sử dụng file.

Để đọc file dữ liệu, ta sử dụng lệnh READ mở rộng dưới dạng:

READ (S hiu thiết b , *) Danh sỏch cỏc biến

Để ghi thụng tin vào file dữ liệu ta sử dụng lệnh WRITE. Giống như lệnh PRINT, lệnh WRITE cú thể sử dụng để xuất thụng tin ra dưới dạng danh sỏch liệt kờ và dưới dạng ghi khụng định dạng hoặc cú định dạng:

WRITE (S hiu thiết b, *)Danh sỏch cỏc biu thc

WRITE(S hiu thiết b , n) Danh sỏch cỏc biu thc

trong đú n là nhón của lệnh FORMAT (định dạng) tương ứng. Trong tất cả cỏc dạng tổng quỏt trờn đõy số hiệu thiết bịphự hợp với số hiệu thiết bịđó gỏn trong lệnh OPEN. Dấu sao * đứng sau số hiệu thiết bịchỉ rằng ta đang sử dụng cỏch nhập và xuất khụng định dạng (khụng format).

Cỏc mỏy tớnh cú thể cú một số thiết bị nhập hoặc xuất đi kốm. Mỗi thiết bị được gỏn một số hiệu. Thớ dụ, nếu mỏy in lazer được gỏn số hiệu 8 thỡ lệnh in sau đõy sẽ ghi giỏ trị của cỏc biến XY ra mỏy in laser

WRITE (8 , *) X, Y

Đa số cỏc hệ mỏy tớnh gỏn thiết bị nhập chuẩn (bàn phớm) bằng số 5

và thiết bị xuất chuẩn (màn hỡnh) bằng số 6; những thiết bị này đó được dựng ngầm định với cỏc lệnh READ * hay PRINT *. Do đú khụng nờn dựng những số hiệu thiết bị đó gỏn trước này cho cỏc file dữ liệu. Ta cú thể dựng bất kỳ những số hiệu khỏc trong cỏc số nguyờn từ 1 đến 15 để chỉ đơn vị file.

Sau khi kết thỳc đọc hoặc ghi file, cỏc file tự động đúng lại trước khi chương trỡnh kết thỳc. Cũng cú những trường hợp ta muốn chủ tõm đúng hay tỏch một file khỏi chương trỡnh của mỡnh, và điều này nờn làm. Ta sẽ dựng lệnh đúng file cú dạng tổng quỏt như sau:

CLOSE (UNIT = Biu thc nguyờn)

Những lệnh mở, đúng file, xuất nhập thụng tin với file trờn đõy cũn cú nhiều tuỳ chọn bổ sung khỏc nữa, sẽ được nhắc tới ở những nơi thớch hợp trong cỏc mục và cỏc chương sau.

Dưới đõy túm tắt một số quy tắc quan trọng cần nhớ khi đọc dữ liệu từ cỏc file:

54

một bản ghi (record). Nếu cũn thừa cỏc giỏ trị ở dũng trước, thỡ những giỏ trị đú bị bỏ qua khụng đọc.

2. Nếu một dũng khụng chứa đủ cỏc giỏ trị so với danh sỏch cỏc biến cần đọc trong lệnh READ, thỡ cỏc dũng dữ liệu sau đú sẽ tự động được đọc cho đến khi đủ giỏ trị cho cỏc biến liệt kờ trong lệnh READ.

3. Một lệnh READ khụng cần phải đọc tất cả cỏc giỏ trị trờn dũng dữ liệu hiện thời. Nhưng nú phải đọc tất cả những giỏ trị trờn dũng ở trước giỏ trị mà ta muốn nú đọc. Thớ dụ nếu một file cú 5 giỏ trị ghi trờn một dũng và ta cần cỏc giỏ trị thứ ba và thứ tư, ta phải đọc qua cỏc giỏ trị thứ nhất và thứ hai để đạt tới cỏc giỏ trị thứ ba và thứ tư, nhưng ta khụng cần phải đọc giỏ trị thứ năm.

Để sử dụng đỳng lệnh READ, ta cần biết cỏc giỏ trị đó được ghi trong file như thế nào. Thớ dụ, giả sử rằng mỗi dũng của file dữ liệu chứa hai số tuần tự biểu thị thời gian TIME và số đo nhiệt độ TEMP và ba dũng đầu tiờn ghi như sau:

0.0 28.3 (dũng 1)

0.1 29.1 (dũng 2)

0.2 29.5 (dũng 3)

thỡ lệnh sau đõy sẽ đọc được đỳng một cặp giỏ trị thời gian và nhiệt độ từ file dữ liệu

READ (10, *) TIME, TEMP Nhưng sẽ là sai nếu ta dựng hai lệnh sau

READ (10, *) TIME READ (10, *) TEMP

Thực hiện hai lệnh này sẽ đọc hai dũng của file dữ liệu: giỏ trị của biến TIME sẽ bằng 0.0 và giỏ trị của biến TEMP sẽ bằng 0.1. Trong trường hợp này chương trỡnh vẫn làm việc bỡnh thường nhưng kết quả xử lý sẽ sai.

Thớ dụ này minh hoạ sự quan trọng của việc kiểm tra chương trỡnh của chỳng ta đối với dữ liệu đó biết, trước khi sử dụng nú với file dữ liệu khỏc.

6.3. K thut đọc cỏc file d liu

Để đọc cỏc dữ liệu từ file dữ liệu, trước hết ta phải biết một số thụng tin về file. Ngoài tờn file, ta phải biết dữ liệu gỡ được lưu trong file và cụ thể ghi như thế nào: cú bao nhiờu số ghi trờn một dũng và cỏc đơn vị đo của mỗi giỏ trị. Ta cũng phải biết trong file cú thụng tin gỡ đặc biệt cú ớch để phõn định được số dũng ghi trong file, hay để xỏc định khi nào ta đó đọc hết dũng ghi cuối cựng. Thụng tin này quan trọng, vỡ nếu ta thực hiện một lệnh READ sau khi tất cả cỏc dũng ghi trong file đó được đọc hết rồi thỡ sẽ bị lỗi thực hiện chương trỡnh. Ta cú thể trỏnh lỗi đú bằng cỏch sử dụng thụng tin về file để quyết định xem loại vũng lặp nào nờn dựng khi đọc file. Thớ dụ, nếu ta biết cú 200 dũng ghi trong file thỡ đương nhiờn cú thể dựng vũng lặp DO thực hiện 200 lần đọc và tớnh toỏn với số liệu đọc được. Nhiều khi ta khụng biết trước cú bao nhiờu dũng ghi trong file, nhưng ta biết dũng ghi cuối cựng chứa những giỏ trị đặc biệt làm cho chương trỡnh của chỳng ta cú thể kiểm tra được. Thớ dụ, nếu một file chứa cỏc số liệu về thời gian và số đo nhiệt độ dưới dạng hai cột, thỡ cả hai cột ở dũng cuối cựng nờn chứa hai số 999 để ký hiệu rằng đõy là dũng cuối cựng của file. Trong trường hợp này ta cú thể lập vũng lặp While để đọc cỏc dũng số liệu và điều kiện kết thỳc vũng lặp này là hai giỏ trị thời gian và nhiệt độ đều bằng 999. Cú trường hợp ta khụng biết cú bao nhiờu dũng ghi và ở cuối file cũng khụng cú cỏc giỏ trị đặc biệt để nhận biết. Khi đú ta phải nhờ đến cỏc tuỳ chọn (options) của lệnh READ.

6.3.1. Số dũng ghi được chỉđịnh

Nếu ta biết chắc số dũng ghi, cú thể dựng vũng lặp DO để xử lý file. Khi tạo lập file, ngay ở dũng ghi đầu, ta nờn ghi một số thụng tin chuyờn

55

dụng về file, trong đú cú số dũng ghi (số số liệu) trong file. Về sau, mỗi lần bổ sung số liệu vào file dữ liệu, ta cần sửa lại dũng ghi này. Khi xử lý file, ta đọc số này vào một biến. Sau đú dựng vũng lặp DO với biến đú làm giới hạn cuối của vũng lặp để đọc hết số liệu trong file.

Thớ d 14: Cỏch đọc file cú thụng tin v s dũng s liu dũng đầu file. Giả sử file cú tờn là SOLIEU.DAT chứa cỏc giỏ trị trung bỡnh ngày của nhiệt độ, độ ẩm khụng khớ và ỏp suất khớ quyển tại một trạm quan trắc trong nhiều ngày. Mỗi dũng của file ghi tuần tự ba đại lượng trờn cho một ngày. Riờng dũng thứ nhất ghi tổng số số liệu (số ngày). Đoạn chương trỡnh đọc số liệu từ file này và tớnh giỏ trị trung bỡnh của ba đại lượng cú thể như sau:

INTEGER N, K

REAL ND, DA, AS, NDTB, DATB, ASTB

OPEN (UNIT = 2, FILE = 'SOLIEU.DAT', STATUS = 'OLD')

READ (2 ,*) N IF (N .LT. 1) THEN

PRINT *, ' TRONG FILE KHONG CO SO LIEU '

ELSE NDTB = 0.0 DATB = 0.0 ASTB = 0.0 DO 15 K = 1, N READ (2, *) ND, DA, AS NDTB = NDTB + ND DATB = DATB + DA ASTB = ASTB + AS 15 CONTINUE NDTB = NDTB / REAL (N) DATB = DATB / REAL (N) ASTB = ASTB / REAL (N)

PRINT 25 , N, NDTB, DATB, ASTB

END IF

25 FORMAT (1X, 'SO NGAY = ' , I5 , ' ND =' , F6.2 , ' DA =' , * F6.2 , ' AS =' , F7.1)

CLOSE (2)

END

Trong thớ dụ này, số số liệu được đọc từ dũng thứ nhất của file và gỏn vào biến N. Lệnh IF kiểm tra nếu N1 thỡ thụng bỏo khụng cú số liệu; nếu cú số liệu thỡ đọc hết tất cả số liệu và tớnh cỏc giỏ trị trung bỡnh. Và ta thấy biến N được dựng làm tham số giới hạn cuối của lệnh DO.

6.3.2. Dũng ký hiệu kết thỳc dữ liệu

Những giỏ trị đặc biệt dựng để đỏnh dấu sự kết thỳc của file dữ liệu gọi là ký hiệu kết thỳc (Trailer hay Flags). Khi tạo lập file, ta thờm một số con số đặc biệt trong dũng ghi cuối cựng. Về sau, nếu ta thờm hoặc xúa đi một số số liệu trong file, sẽ khụng phải sửa lại số ghi tổng số số liệu. Tuy nhiờn, nếu dựng phương phỏp này để đỏnh dấu hết file, thỡ phải cẩn thận sao cho chương trỡnh của chỳng ta khụng được đưa những giỏ trị đặc biệt vào xử lý như cỏc giỏ trị bỡnh thường khỏc. Cú thể chỳng ta phải ghi chỳ về điều này ở dũng đầu file. Ngoài ra, nếu dũng số liệu bỡnh thường chứa bao nhiờu giỏ trị thỡ dũng ký hiệu kết thỳc cũng nờn cú chừng đú giỏ trị đặc biệt

56

để đảm bảo cho lệnh đọc khụng mắc lỗi chạy chương trỡnh. Người ta thường chọn cỏc giỏ trị đặc biệt sao cho chỳng khỏc hẳn với những giỏ trị bỡnh thường, dễ nhận ra khi xem bằng mắt cỏc số liệu trong file, thớ dụ như số nguyờn lớn nhất 32767, một tập hợp cỏc số chớn như 99999. Ta cũng cú thể dựng cỏch này để đỏnh dấu những giỏ trị khuyết trong cỏc chuỗi số liệu (Flags- cờ hiệu bỏo hết file hoặc khuyết số liệu).

Thớ d 15: Cỏch đọc file cú dũng s liu đỏnh du hết file cui file và c hiu bỏo khuyết s liu. Giả sử file dữ liệu với nội dung như trong thớ dụ 14, nhưng được tạo ra theo cỏch đỏnh dấu kết thỳc dữ liệu bằng dũng gồm ba cụm số 99999. Ngoài ra, trong cỏc dũng số liệu bỡnh thường cú những giỏ trị khuyết, khụng quan trắc, được đỏnh dấu bằng con số 32767. Chương trỡnh sau đõy cho phộp đọc và tớnh toỏn đỳng cỏc trị số trung bỡnh của ba đại lượng:

INTEGER N1, N2, N3

REAL ND, DA, AS, NDTB, DATB, ASTB

OPEN (UNIT = 2, FILE = 'SOLIEU.DAT', STATUS = 'OLD') N1 = 0 N2 = 0 N3 = 0 NDTB = 0.0 DATB = 0.0 ASTB = 0.0 60 READ (2, *) ND, DA, AS

IF (ND.NE. 99999 .OR. DA .NE. 99999 .OR. AS .NE. 99999) THEN

IF (ND .NE. 32767.) THEN

NDTB = NDTB + ND N1 = N1 + 1

END IF

IF (DA .NE. 32767.) THEN

DATB = DATB + DA N2 = N2 + 1

END IF

IF (AS .NE. 32767.) THEN

ASTB = ASTB + AS N3 = N3 + 1 END IF GOTO 60 END IF CLOSE (2)

IF (N1 .EQ. 0 .AND. N2 .EQ. 0 .AND. N3 .EQ. 0) THEN

PRINT * , ' TRONG FILE KHONG CO SO LIEU '

ELSE

IF (N1 .GT. 0) PRINT * , ' NHIET DO TRUNG BINH = ', * NDTB / REAL (N1)

IF (N2 .GT. 0) PRINT * , ' DO AM TRUNG BINH = ', * DATB / REAL (N2)

IF (N3 .GT. 0) PRINT * , ' AP SUAT TRUNG BINH = ', * ASTB / REAL (N3)

END IF

END

6.3.3. Sử dụng tuỳ chọn END

Trường hợp khụng biết số dũng dữ liệu trong file và khụng cú dũng thụng tin về dấu hiệu kết thỳc dữ liệu trong file, ta phải sử dụng một kỹ

57

thuật khỏc. Lệnh READ trong Fortran cú một tuỳ chọn giỳp kiểm tra sự kết thỳc của file và rẽ nhỏnh sang một lệnh được chỉ định nếu phỏt hiện hết file. Lệnh READ với tuỳ chọn này cú dạng sau:

READ (S hiu file , * , END = n) Danh sỏch cỏc biến

Khi nào cũn dữ liệu trong file lệnh này thực hiện giống như lệnh READ (Số hiệu file , *) Danh sỏch cỏc biến

Tuy nhiờn, nếu dũng dữ liệu cuối cựng đó đọc xong và ta thực hiện lệnh READ với tựy chọn END thỡ thay vỡ phạm lỗi thực hiện lệnh, điều khiển được chuyển tới lệnh cú nhón n trong tuỳ chọn END. Nếu lệnh READ thực hiện một lần nữa sau khi đó đạt đến cuối file, thỡ lỗi chạy chương trỡnh sẽ xuất hiện.

Lệnh READ với tuỳ chọn END thực sự là một dạng đặc biệt của vũng lặp điều kiện While:

5 READ (10, *, END = 15) TEMP SUM = SUM + TEMP

N = N +1

GOTO 5

15 PRINT * , SUM

Dạng đặc biệt này của vũng lặp điều kiện chỉ nờn thực hiện khi nào ta khụng biết số dũng dữ liệu và khụng cú dũng ký hiệu bỏo hết dữ liệu. Việc chọn kỹ thuật hợp lý để đọc dữ liệu từ file phụ thuộc vào thụng tin trong file dữ liệu.

Thớ d 16: S dng tựy chn END. Với file dữ liệu nội dung như trong thớ dụ 14, giả sử khụng cú dũng đầu tiờn thụng bỏo về độ dài chuỗi dữ liệu, ta thực hiện chương trỡnh tớnh cỏc trị số trung bỡnh như sau:

INTEGER N, K

REAL ND, DA, AS, NDTB, DATB, ASTB

OPEN (UNIT = 2, FILE = 'SOLIEU.DAT', STATUS = 'OLD') NDTB = 0.0

DATB = 0.0 ASTB = 0.0 N = 0

C Nếu đọc hết số liệu tựy chọn END = 15 sẽ chuyển đến lệnh 15

5 READ (2, *, END = 15) ND, DA, AS

NDTB = NDTB + ND DATB = DATB + DA ASTB = ASTB + AS N = N + 1 GOTO 5 15 CLOSE (2) IF (N .EQ. 0) THEN

PRINT *, ' TRONG FILE KHONG CO DU LIEU' ELSE

NDTB = NDTB / REAL (N) DATB = DATB / REAL (N) ASTB = ASTB / REAL (N)

PRINT 25 , N, NDTB, DATB, ASTB END IF

25 FORMAT (1X, ' SO NGAY = ', I5 , ' ND =' , F6.2 , ' DA =' , * F6.2 , ' AS =' , F7.1)

58 6.4. To lp cỏc file d liu

Để tạo mới file dữ liệu, chỳng ta sử dụng cỏc lệnh OPEN và WRITE. Tuy nhiờn, trước khi ta bắt đầu viết cỏc lệnh Fortran, cần cõn nhắc xem sau này đọc file dữ liệu sẽ sử dụng kỹ thuật nào trong ba kỹ thuật đó mụ tả trong mục 6.3.

Khi tạo lập file với dũng ký hiệu bỏo hết dữ liệu phải cẩn thận lựa chọn giỏ trị dựng làm ký hiệu. Phải tin chắc rằng giỏ trị được chọn làm giỏ trị bỏo hết dữ liệu khụng thể nào nhầm với giỏ trị dữ liệu thực sự. Cú thể chỳng ta phải cú ghi chỳ ở đầu file để mọi người dựng file được biết.

Nếu ta quyết định tạo file với thụng tin bỏo tổng số dũng dữ liệu trờn đầu file, thỡ phải chỳ ý cập nhật dũng đầu file mỗi khi bổ sung hoặc cắt bớt số dũng dữ liệu. Nếu số dũng dữ liệu khụng đỳng, thỡ hoặc chương trỡnh đọc sẽ đọc số dũng dữ liệu ớt hơn số dũng thực cú, hoặc chương trỡnh cố đọc nhiều dũng hơn trong file thực cú và dẫn đến lỗi trong khi chạy chương trỡnh.

So sỏnh ba phương ỏn tổ chức thụng tin dữ liệu ở trờn, ta thấy về phương diện tối ưu chương trỡnh thỡ cỏch dựng số bỏo số dũng dữ liệu ở đầu file là tốt hơn cả, vỡ khi đọc được tổng số dũng số liệu ta cú thể đọc hết dữ liệu bằng vũng lặp DO, trong khi hai phương ỏn sau chương trỡnh luụn luụn phải kiểm tra biểu thức lụgic trong khi đọc lặp. Ngoài ra rất cú thể cú những nhiệm vụ xử lý khụng cần đọc hết file, mà chỉ cần đọc số lượng số liệu của file ở dũng đầu.

Một phần của tài liệu Ngôn ngữ lập trình Fortran và ứng dụng trong khí tượng thủy văn (Trang 53 - 59)

Tải bản đầy đủ (PDF)

(112 trang)