ข้อผิดพลาด: ต้องใช้เครื่องหมายจุลภาคหลัง P descriptor ในรูปแบบสตริง

เมื่อฉันพยายามคอมไพล์ calrank.for (CALRANK_v7.0.0_L140912.zip) ด้วย gfortran ฉันได้รับข้อผิดพลาดนี้:

> gfortran  -m64 -c -o calrank.o calrank.for
calrank.for:1922:32:
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
                                1
Error: Comma required after P descriptor in format string at (1)

เมื่อฉันใส่ลูกน้ำ ฉันได้รับข้อผิดพลาดเดียวกัน
ฉันสังเกตเพียงว่าโค้ดนี้เคยถูกคอมไพล์มาก่อนด้วย LF95

   subroutine xycout(io,nrank,nsp)
      use userinf
      use header
      use rankdata

      implicit none

    integer :: io,nrank,nsp
      integer :: k,ir,is,i
      character(len=20)   :: head1,head2,head3
      character(len=40)   :: add1x,add2x,add3x
      character(len=40)   :: add1(nsp),add2(nsp)
      character(len=40)   :: add3(nsp)
 ......
 c --- Loop over receptors to write data records
      do ir=1,ntotrec(k)
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
     &                   xreckm(ir,k),yreckm(ir,k),
     &                  (xounit(is,k)*rankvalue(ir,is,nrank),
     &                   arankdate(ir,is,nrank),
     &                   aranktime(ir,is,nrank),is=1,nspout(k))
      enddo

      return
      end

ตัวแปรบางตัวถูกกำหนดไว้ที่อื่นของโค้ดดังนี้:

c --- Real arrays for header (derived)
      allocate (xreckm(mxrec,k),yreckm(mxrec,k))
c --- Modified units multiplier
      allocate (xounit(mxspout,k))
      c --- Array of values (all species, receptors) for requested ranks
      allocate (rankvalue(ntotrec(k),nspout(k),n_ranks))
      allocate (arankdate(ntotrec(k),nspout(k),n_ranks))
      allocate (aranktime(ntotrec(k),nspout(k),n_ranks))
c --- Integer arrays for header
      deallocate (ndrec,nctrec,nspout,i2dmet,iutmzn)

person Moustabchir Rachid    schedule 01.03.2019    source แหล่งที่มา
comment
ยินดีต้อนรับ โปรดเข้าร่วมทัวร์ชม ใช้ fortran เสมอสำหรับคำถาม Fortran ทั้งหมด โดยปกติเราต้องการโค้ดมากกว่าที่ข้อความแสดงข้อผิดพลาดแสดง อย่างน้อยที่สุด ตัวแปรทั้งหมดในตัวอย่างของคุณต้องได้รับการประกาศ   -  person Vladimir F    schedule 01.03.2019
comment
ขอโทษด้วยกับเรื่องนั้น. ฉันไม่พบวิธีการอัปโหลดรหัส ฉันแชร์ใน drive.google.com/file/d/1viIilSckdGUgoZ9r2SSPbgOXKqK1Blsu/. ขอบคุณ. รหัสมาจาก src.com/calpuff/download/mod7_codes.htm CALRANK เวอร์ชัน 7.0.0 (140912)   -  person Moustabchir Rachid    schedule 01.03.2019
comment
คุณไม่ควรอัปโหลดรหัสของคุณทุกที่ คุณควรคัดลอกและวาง ตัวอย่างที่ทำซ้ำได้น้อยที่สุด ที่เกี่ยวข้อง (สังเกตอีกครั้งว่าคำว่า minimal) ในคำถามของคุณ เป็นข้อความ แก้ไขคำถามเพื่อให้มีส่วนสำคัญของโค้ด   -  person Vladimir F    schedule 01.03.2019
comment
โอเค ขอบคุณมากนะวลาดิมีร์   -  person Moustabchir Rachid    schedule 01.03.2019
comment
ไม่ต้องกังวลเกี่ยวกับมันตอนนี้ดูคำตอบ   -  person Vladimir F    schedule 01.03.2019


คำตอบ (2)


คุณควรดำเนินการตามที่ข้อความแสดงข้อผิดพลาดระบุ โดยใส่ลูกน้ำหลัง p descriptor:

write(io,'(2f10.3,1p,1000(2x,e16.7,1x,2a10,1x))')

หากคุณไม่ทราบว่า p descriptor คืออะไร โปรดดูตัวอย่าง https://docs.oracle.com/cd/E19957-01/805-4939/z4000743a6e2/index.html หรือบทช่วยสอนเกี่ยวกับตัวอธิบายการแก้ไข Fortran ตามที่ Steven Lionel แสดงความคิดเห็นด้านล่าง คุณสามารถใช้ p descriptor โดยไม่ต้องใส่ลูกน้ำหน้าคำอธิบายการแก้ไขข้อมูลปกติ

person Vladimir F    schedule 01.03.2019
comment
ขอบคุณมากวลาดิเมียร์ มันกำลังทำงานอยู่ ใช่ ฉันไม่เคยใช้ p descriptor แต่นี่เป็นครั้งแรกที่ฉันเห็นมัน - person Moustabchir Rachid; 01.03.2019
comment
มันไม่มีประโยชน์มาก ฉันไม่เคยใช้มัน เลยไม่ตอบมาก่อนเลยต้องตรวจสอบรายละเอียดด้วยตัวเอง - person Vladimir F; 01.03.2019
comment
รูปแบบ P มีประโยชน์แต่ยังไม่เป็นที่เข้าใจดีนัก กฎเกี่ยวกับการละเว้นเครื่องหมายจุลภาคนั้นยังไม่ค่อยเข้าใจอีกด้วย เครื่องหมายจุลภาคอาจถูกละไว้ระหว่างตัวอธิบายการแก้ไข P และตัวอธิบายการแก้ไข F, E, EN, ES, EX, D หรือ G ที่ตามหลังทันที ซึ่งอาจนำหน้าด้วยข้อกำหนดการทำซ้ำ แต่ในกรณีนี้ สิ่งที่ตามมาคือกลุ่มที่อยู่ในวงเล็บและไม่เข้าเกณฑ์ - person Steve Lionel; 01.03.2019
comment
ขอบคุณ Vladimir F, Steve Lionel และ francescalus เป็นอย่างมากสำหรับการชี้แจงเหล่านี้ ฉันสงสัยว่าตัวเลข 1,000 ที่มาหลัง 1p มีความหมายว่าอะไร? ซ้ำ 1,000 ครั้งมั้ย!!! - person Moustabchir Rachid; 01.03.2019
comment
โอเค ฉันควรจะบอกว่าฉันพบว่าตัวอธิบาย P ใช้ยากและอันตราย โดยเฉพาะเรื่องการป้อนข้อมูล @MoustabchirRachid ใช่ 1,000 เป็นการซ้ำซ้อนของกลุ่มในวงเล็บ เราสามารถใส่ตัวเลขจำนวนมากไว้ตรงนั้นได้อย่างปลอดภัย หรือแม้แต่การทำซ้ำอย่างไม่มีกำหนด * หากกลุ่มที่ซ้ำกันอยู่ที่ส่วนท้ายของสตริงรูปแบบ และกลุ่มหนึ่งไม่ต้องการให้มีการเปลี่ยนรูปแบบใดๆ เกิดขึ้น - person Vladimir F; 01.03.2019

@francescalus แนะนำให้ฉันขยายความคิดเห็นของฉัน

อันดับแรก โดยทั่วไปแล้ว Fortran ต้องมีเครื่องหมายจุลภาคระหว่าง "รายการรูปแบบ" สองรายการ รายการรูปแบบคือตัวอธิบายการแก้ไข (F, E ฯลฯ) โดยมีหรือไม่มีการนับซ้ำนำหน้า หรือกลุ่มของรายการรูปแบบที่อยู่ในวงเล็บ (ซึ่งอาจมีการนับซ้ำของตัวเอง @Vladimir F กล่าวถึง * - นี่คือ " นับซ้ำไม่จำกัด" และใช้ได้กับกลุ่มที่อยู่ในวงเล็บเท่านั้น

เครื่องหมายจุลภาคอาจถูกละเว้น:

  • ระหว่างตัวอธิบายการแก้ไข P และตัวอธิบายการแก้ไข F, E, EN, ES, EX, D หรือ G ที่ตามมาทันที ซึ่งอาจนำหน้าด้วยข้อกำหนดการทำซ้ำ
  • หน้าตัวอธิบายการแก้ไขเครื่องหมายทับเมื่อข้อกำหนดการทำซ้ำที่เป็นตัวเลือกไม่ปรากฏขึ้น
  • หลังตัวอธิบายการแก้ไขเครื่องหมายทับหรือ
  • ก่อนหรือหลังตัวอธิบายการแก้ไขโคลอน

สำหรับตัวอธิบายการแก้ไข P สิ่งนี้จะตั้งค่าสเกลแฟคเตอร์ และมันแปลกจริง ๆ และมีเอฟเฟกต์ที่แตกต่างกันมาก ขึ้นอยู่กับว่าคุณกำลังแก้ไขประเภทใด นอกจากนี้ยัง "ติดหนึบ" และใช้กับการแก้ไขทั้งหมดในรูปแบบนั้นในภายหลัง

ในอินพุต จะทำให้ค่าการอ่านหารด้วย 10**k โดยที่ k คือตัวประกอบสเกล (2P หมายถึง k=2 เป็นต้น) ดังนั้นหากอักขระในอินพุตเป็น 123 และมีผลใช้งาน 2P ค่าจะอ่านเป็น 1.23 ในทำนองเดียวกัน หากมีผลใช้ -2P 123 จะอ่านเป็น 12300 จุดทศนิยมในอินพุตจะไม่เปลี่ยนแปลง แต่เลขชี้กำลังจะลบมาตราส่วนออก ดังนั้น 1.23 อ่านด้วย 2P คือ .0123 แต่ 1.23E0 คือ 1.23

ในเอาต์พุตที่มีการแก้ไข F จะทำให้ค่าเอาต์พุตคูณด้วย 10**k โดยกลับรายการโครงร่างอินพุต

คุณอาจถามว่าทำไม??? คำตอบอยู่ในบัตรเจาะ ซึ่งเป็นรูปแบบอินพุต (และบางครั้งก็เป็นเอาท์พุต) ที่ใช้ในช่วงทศวรรษ 1950 ถึง 1970 สิ่งเหล่านี้มี 80 คอลัมน์ และการสิ้นเปลืองคอลัมน์ด้วยจุดทศนิยมอาจเป็นปัญหาได้ ดังนั้นตัวประกอบมาตราส่วนทำให้สามารถละจุดทศนิยมได้แต่ยังคงได้เศษส่วนอยู่

แต่เดี๋ยวก่อน มันเริ่มแปลกขึ้น! ในเอาต์พุตที่มีการแก้ไข E และ D ตัวประกอบสเกลจะกำหนดจำนวนหลักนำหน้าทางด้านซ้ายของจุดทศนิยม (และการลดเลขชี้กำลังในเวลาต่อมา ดังนั้น สำหรับค่า 1.23 และรูปแบบ 2P, E11.3 คุณจะได้รับ b12.300E-01 (b=blank เว้นแต่ว่า SP จะมีผลใช้งาน ซึ่งเป็นการตอบกลับไปอีกวัน)

และสำหรับเอาต์พุตด้วยรูปแบบ G? แปลกกว่าด้วยซ้ำ หากค่าอยู่ในช่วงที่คุณได้รับเทียบเท่ากับรูปแบบ F ตัวประกอบสเกลจะไม่มีผลใดๆ มิฉะนั้นจะทำงานเหมือนกับ E

สุดท้ายนี้ ตัวคูณสเกลจะไม่ส่งผลต่อการแก้ไข EN, ES หรือ EX (เช่นนั่นคือฟีเจอร์ F2018 สำหรับเอาต์พุตจุดทศนิยมฐานสิบหก)

การใช้รูปแบบ P ที่ดีอย่างหนึ่งคือเมื่อทำการคำนวณสกุลเงินด้วยจำนวนเต็มแทนที่จะเป็นจำนวนจริง เนื่องจากรูปแบบหลังอาจสูญเสียความแม่นยำ (เช่น .01 ไม่มีการแสดงค่าทศนิยมแบบทศนิยมที่แน่นอน) สมมติว่าค่าที่คุณกำลังเผชิญอยู่นั้นไม่เป็นเช่นนั้นเช่นกัน ใหญ่ คุณสามารถอ่านดอลลาร์และเซนต์เป็นจำนวนเต็มด้วยรูปแบบ -2P และไม่เสียเพนนีใดๆ ในการบวก ลบ และคูณ ฉันเคยเขียนเครื่องคำนวณสินเชื่อในลักษณะนี้ที่แม่นยำ

person Steve Lionel    schedule 02.03.2019