This question already has answers here:
Line truncated, Syntax error in argument list
(2 answers)
Closed 3 years ago.
I am trying to make a program about a cantilever arm.
program statik
implicit none
integer :: i;
real :: x, stuetzlaenge, belastung, einzellastlaenge, einzellast, auflagerkraft, querkraft, moment;
logical :: debugging
debugging = .false.
if (debugging) then
stuetzlaenge = 1.0
belastung = 1.0
else
print *, 'Statik: Kragarm unter Gleichlast mit Einzellast an beliebiger Stelle'
print *, 'Bitte geben Sie die Geometrie und die Belastungen ein: '
write(*,100) '- Stuetzlaenge l [m] = '
read(*,*) stuetzlaenge
write(*,100) '- Gleichlast q [kN/m] = '
read(*,*) belastung
write(*,100) '- Lage der Einzellast a [m] = '
read(*,*) einzellastlaenge
write(*,100) '- Einzellast F [kN] = '
read(*,*) einzellast
end if
print *, 'Eingaben:'
print *, '- Stuetzlaenge l [m] = ', stuetzlaenge
print *, '- Gleichlast q [kN/m] = ', belastung
print *, '- Lage der Einzellast a [m] = ', einzellastlaenge
print *, '- Einzellast F [kN] = ', einzellast
print *, 'Ergebnisse:'
auflagerkraft = belastung*stuetzlaenge + einzellast;
print *, '- Auflagerkraft: A = ', auflagerkraft , ' kN'
print *, '- Querkraefte:'
do i = 0, 10
x = stuetzlaenge*i/10 [m];
querkraft = auflagerkraft - belastung*x - if(einzellastlaenge == x) then write(*,*) "einzellast" else if(einzellastlaenge > x)then write(*,*)"0";
print *, ' Q(x=',x,') = ', querkraft, 'kN'
end do
print *, '- Momente:'
do i = 0, 10
x = stuetzlaenge*i/10;
moment = belastung*stuetzlaenge*stuetzlaenge/2 - belastung*x*x/2 - if(einzellastlaenge == x) then write(*,*) "einzellast*einzellastlaenge";
print *, ' M(x=',x,') = ', moment, 'kNm'
end do
100 format(1X,A)
end program statik
the errors:
1 Error: Line truncated at (1)
[-Werror=line-truncation]
main.f95:49:97:
moment = belastung*stuetzlaenge*stuetzlaenge/2 - belastung*x*x/2 - if(einzellastlaenge == x) then write(*,*) "einzellast*einzellastlaenge";
1
Error:
Invalid character in name at (1)
main.f95:50:1:
Apart from those lines being syntactically incorrect, they are also too long. Either break them down using line continuation (&), or extend the number of considered columns per line.
Assuming you are using gfortran (from the error messages), this is done using -ffree-line-length-0 or -ffree-line-length-none.
Related
I have to make an app that edits a todo list (file to_do.txt). I can read it and also I can add new tasks, but I cannot remove a specific line of the file without destroying everything. How can I do it? This is my code
program compito4
implicit none
! Declaring the variables
integer :: unit, stat, counter, i
character (len = 1) action
character (len = 200) line, new_task
! Open the program
open(newunit = unit, file = 'to_do.txt', status = 'OLD', position = 'APPEND')
do
print *, 'What would you like to do? (a)dd, (d)elete, (l)ist, (q)uit'
read (*,*) action
if (action == 'a') then
print *, 'Insert the new task'
read (*, '(A)') new_task
write (unit, '(A)') '\n' // new_task ! // is the string concatenation operator
print *, 'New task successfully added'
else if (action == 'd') then
print *, 'Insert the number of the task to be removed'
read (*,*) i
print *, i
counter = 0
rewind unit
do
read(unit, '(A)', iostat = stat) line
if (stat .ne. 0) then
backspace unit
exit
else if (i == counter) then
print *, 'You are in the right spot'
print *, counter
backspace unit
write (unit, '(2A)') trim(line), ('->Task done')
end if
counter = counter + 1
end do
else if (action == 'l') then
rewind unit
counter = 0
do
read(unit, '(A)', iostat = stat) line
if (stat .ne. 0) then ! It handles the end of file!
backspace unit
exit
end if
print *, counter,') ', line
counter = counter + 1
end do
else if (action == 'q') then
print *, 'Closing the program'
exit
else
print *, 'Invalid choice'
end if
end do
close(unit)
end program compito4
I'm using gfortran 7 (Ubuntu) to compile an old fortran code.
I'm facing the follow error:
MYOLDCODE.f90:864:13:
if (star (i) .eq. ' ' .and.&
1
Error: Operands of comparison operator â.eq.â at (1) are REAL(4)/CHARACTER(1)
I think I'm trying to compare a real number to a blank space char. I don't know why the original coder do this. He dead in 90's so I can only ask him when I go to same place he is now, but then it will be too late. Here are the code:
DO I = 1,KJ
( some code )
WRITE(impre,7100,IOSTAT=IERRO) I,STAR(I),A2(I),B2(I),A3(I),AMPL(I),&
&CIA(I),SITU(I),A4(I),A5(I),CIF(I)
if (star (i) .eq. ' ' .and.&
& ampl (i) .ne. 1.E20 .and.&
& ampl (i) .ge. 0.5 .and.&
& situ (i) .ne. 1.E20 ) then
write (15,7777) a2(i), b2(i), a3(i), ampl(i), situ(i)
end if
7777 format (a3,a4,f11.7,f8.2,f8.2)
end do
7100 FORMAT (t25,I3,2X,A1,A3,A4,2X,F11.7,6(2X,F8.2) )
How can I compare star (i) .eq. ' ' ?
I know nothing about fortran so please ask if you need more code/information
subroutine mindef(f)
implicit real*8(a-h,o-z)
real*8 r(6),com(3)
data r/"en d", "irec","tion","prog","ress","ion "/, &
& nl , ng , np/"l" , "g" , "p"/, "itra1","itra2"/"*" , " "/
I got the following message:
fitold.f90:346:39:
& nl , ng , np/"l" , "g" , "p"/, "itra1","itra2"/"*" , " "/
1
Error: Syntax error in DATA statement at (1)
A data statement takes pairs of object lists and value lists, where such a pair is of the form object-list /value-list/. The objects (excluding cases of data implied dos) to be initialized must be variables. In the case of the data statement of the question, this is violated around the point of the error message marker.
Let's look at the statement of the question:
data r / "en d", "irec","tion","prog","ress","ion " / , &
! ^ ^ '----------------------------------------' ^ ^
! | | '- value list | '- pair separator
! | '- separator '- separator
! '- variable name
& nl , ng , np / "l" , "g" , "p" / , "itra1","itra2" /"*" , " "/
! '-----------' ^ '--------------' ^ ^ '--------------'
! '- object | '- value | | '- NOT VARIABLES!
! list | list | '- pair separator
! '- separator '- separator
As we now see, we have character literals where the compiler expects to see object names.
As tim18 comments, even this correction won't make the code fragment standard Fortran. Some compilers accept character values for initializing/assigning to real values (and real*8), but this isn't universal.
How do I invoke a program and pass it standard input? Hypothetical example in Bash:
(echo abc; echo abba) | tr b B
Note that:
I don't have the input in a string (I'm generating it as I iterate)
I don't know how long input is
The input may span multiple lines, as in this example
I've written this in 19 other languages already, the way I usually approach it is to get a file descriptor for the program's standard input, and then write to the file descriptor the same way I would write to standard output.
What I've tried so far: Based on Invoke external program and pass arguments I tried passing it to echo and using the shell to handle the piping. This doesn't work if my input has single quotes in it, and it doesn't work if I don't have my input in a string (which I don't)
Here is my code, currently trying to pull it off by calculating the string that will be printed (it fails right now).
As for single quotation, how about inserting the escape character (\) before each quotation mark (')...? It seems to be working somehow for the "minimal" example:
module utils
implicit none
contains
function esc( inp ) result( ret )
character(*), intent(in) :: inp
character(:), allocatable :: ret
integer :: i
ret = ""
do i = 1, len_trim( inp )
if ( inp( i:i ) == "'" ) then
ret = ret // "\'"
else
ret = ret // inp( i:i )
endif
enddo
endfunction
endmodule
program test
use utils
implicit none
character(100) :: str1, str2
integer i
call getcwd( str1 ) !! to test a directory name containing single quotes
str2 = "ab'ba"
print *, "trim(str1) = ", trim( str1 )
print *, "trim(str2) = ", trim( str2 )
print *
print *, "esc(str1) = ", esc( str1 )
print *, "esc(str2) = ", esc( str2 )
print *
print *, "using raw str1:"
call system( "echo " // trim(str1) // " | tr b B" )
print *
print *, "using raw str2:"
call system( "echo " // trim(str2) // " | tr b B" ) !! error
print *
print *, "using esc( str1 ):"
call system( "echo " // esc(str1) // " | tr b B" )
print *
print *, "using esc( str2 ):"
call system( "echo " // esc(str2) // " | tr b B" )
print *
print *, "using esc( str1 ) and esc( str2 ):"
call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | tr b B" )
! pbcopy (copy to pasteboard; mac-only)
! call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | pbcopy" )
endprogram
If we run the above program in the directory /foo/baa/x\'b\'z, we obtain
trim(str1) = /foo/baa/x'b'y
trim(str2) = ab'ba
esc(str1) = /foo/baa/x\'b\'y
esc(str2) = ab\'ba
using raw str1:
/foo/baa/xBy
using raw str2:
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
using esc( str1 ):
/foo/baa/x'B'y
using esc( str2 ):
aB'Ba
using esc( str1 ) and esc( str2 ):
/foo/baa/x'B'y
aB'Ba
This is what I mean by a minimal example.
call execute_command_line("(echo ""hexxo world"";echo abba)|tr x l")
end
hello world
abba
Is this not doing exactly what you ask, invoking tr and passing standard input?
If the input of the following working example ist - for example - "ach_40", the output is "ach_40.DOC?" and "ach_40.IMG". Where is the "?" coming from?
The code is:
program test
character*8 filin
character*12 dummy,file1,file2
character*4 :: img = '.IMG', doc='.DOC'
integer*4 ls1, ls2, i
write(*,*) ' File (without extension): '
read(*,'(a8)') filin
c first file
dummy=filin // doc
ls1 = len_trim(dummy)
ls2=0
do i = 1,ls1
if(dummy(i:i).ne.' ') then
ls2=ls2+1
file1(ls2:ls2) = dummy(i:i)
endif
enddo
c second file
dummy=filin // img
ls1 = len_trim(dummy)
ls2=0
do i = 1,ls1
if(dummy(i:i).ne.' ') then
ls2=ls2+1
file2(ls2:ls2) = dummy(i:i)
endif
enddo
write(*,*) file1
write(*,*) file2
stop
end
Thanks a lot for your hint!!
You never set the value of the whole file1 and file2 so the characters, which you do not explicitly set to something, can be anything.
At the beginning you can set initialize the strings as
file1 = ''
file2 = ''
and they will be filled with spaces which is what you need.
But you probably just want:
file1 = trim(filin) // doc
file2 = trim(filin) // img
instead all of that complicated code.