This question already has an answer here:
Difference between "character*10 :: a" and "character :: a(10)"
(1 answer)
Closed 3 years ago.
I am trying to find the position of a character in a string using the following code.
implicit none
character string(10);
string="abcdefghik"
print *, index(string, "c")
end program test
But the output is 10 times 0 instead of 3. The same happens with the scan function.
What am I doing wrong?
The bug:
You defined your string as an array of single characters of length 10:
character :: string(10)
A character string of length 10 is defined as
character(len=10) :: string
These two are two different concepts. See:
What is the difference between a Char Array and a String?
Difference between "character*10 :: a" and "character :: a(10)"
Why do I get 10 zeros?
The reason you obtained 10 times the value zero is because both INDEX and SCAN are elemental functions. This means that they execute for every element of the array. But this is not all, you would imagine that it would at least return ones the number 1 for the third array ellement. Unfortuntately, the assignment
character array(10)
array = "abcdefghik"
print *, array
will assign 10 times the letter a. You notice that this will return aaaaaaaaaa. This is due to array assignments.
Working code:
program test
implicit none
character(len=10) :: string;
string="abcdefghik"
print *, index(string, "c")
end program test
Related
This question already has answers here:
Why does this C++ char array seem to be able to hold more than its size?
(7 answers)
Closed 2 months ago.
My problem is that array of some size should hold just maximum of characters as the size is, but it does not. Try this code:
char array[6];
cin >> array; //Write for example "123456789", which is nine characters long, so the array should cut last three and hold just "123456"
cout << array; //This displays "123456789" (How come?)
cout << sizeof(array)/sizeof(array[0]) //If array holds "123456789", than this should display number 9, but it displays number 6.
Two different misunderstandings here
First sizeof(array)/sizeof(array[0]) is the size of the array which is 6 (because you said char array[6];. It has nothing to do with what characters the array contains. For the length of the C string that the array contains use strlen not sizeof.
Second, it is true that the maximum number of characters that your array can hold is 6, although if you want the array to be a C string then the limit is 5, because C strings have an extra nul terminator character at the end. Your mistake is in what you expect to happen when you try to exceed that limit. You seem to think that C++ should somehow stop you putting too many characters in the array, but as you have found out it does not. Instead when you put too many characters in the array your program instead will have undefined behaviour. This means that your program could crash, it could print the wrong results, or it could even work, like yours did. Undefined behaviour means that anything could happen.
This question already has an answer here:
Fortran CHARACTER (LEN = *) only apply to dummy argument or PARAMETER
(1 answer)
Closed 1 year ago.
In the mainline, how to I declare "to_upper" and "string" so as to call this function?
Pure Function to_upper (str) Result (string)
! Changes a string to upper case
Implicit None
Character(*), Intent(In) :: str
Character(LEN(str)) :: string
Integer :: ic, i
program tescc
character (*) to_upper, to_lower
character (*) tes1,tes2
tes1='LoWs' tes2=to_upper(tes1)
print*,tes1,',',tes2
end
gfortran -o tescc tescc.f tescc.f:4:24: 4 |
character (*) tes1,tes2 |
1 Error: Entity with assumed character length at (1) must be a dummy argument or a PARAMETER tescc.f:4:29:
You would need to declare three strings, one for the function, one which is the input string, and another for the output string. You would first need to end this function. You need to say the function name is a string because that is what it returns.
This function does nothing so you would need to finish writing the function algorithm. But,
Here is an example code to run this function:
program main
implicit none
character(100) :: to_upper
character(100) :: some_str, other_str
some_str = "hello world"
other_str = to_upper(some_str)
end program main
pure function to_upper (str) Result (string)
! Changes a string to upper case
implicit None
Character(*), Intent(In) :: str
Character(LEN(str)) :: string
Integer :: ic, i
end function
This question already has answers here:
Access elements of returned array in Fortran
(4 answers)
Closed 5 years ago.
I have a function str that takes an integer and converts it to a string. I also want to consider a substring of the string of that value, which would be easy if it were a character value rather than a character function.
In other words, I'd like to write something like this:
str(12345)(2:3)
instead of having to do this:
character(10) :: c
c = str(12345)
print *, c(2:3)
or rolling my own substr() function. Is there any way to do what I want without storing the character value in a temporary character variable or writing another function?
Here's a complete program:
program main
character(10) :: c
! works fine
c = str(12345)
print *, c(2:3)
! nope
print *, str(12345)(2:3)
! this would work if i wrote a substr function
print *, substr( str(12345), 2, 3 )
contains
character(len=1064) function str(k)
! convert an integer to string
integer, intent(in) :: k
write (str, *) k
str = adjustl(str)
end function str
end program main
No, you cannot substring or array-index a Fortran expression. And a function result is an expression. The closest thing to avoiding a temporary is using associate from Fortran 2003, but you won't save much code either
associate(c=>str(12345))
print *,c(2:3)
end associate
I have a third party script for a subroutine that I need to work with. This subroutine is as follows
Subroutine COpen(io, Name )
Character*(*) Name
Character*1023 NameIn, NameOut
NameIn = Trim(Name)//' '
Call Get_OrMakeFileName( NameIn, NameOut )
Open(io,file=NameOut,access="APPEND")
End
I don't understand the Character*(*) name syntax. Isn't the typical way to declare string variables simply. character :: name*4 with the *4 part designating the number of characters? Can anyone please explain the purpose of this alternate syntax? What kind of object does it generate?
In short: character*(*) declares a character variable of assumed length.
There are a number of ways of declaring the length of a character variable. One, as seen in the question's code, is
character*1023 ...
where a literal constant follows the *. Equivalent to that is
character([len=]1023) ...
(len= being optional). In this case the length needn't be a literal constant.
These two forms declare a variable of a particular length. There are two other forms of a length for a character variable:
assumed length - character([len=]*) ... ;
deferred length - character([len=]:) ....
Like with character*1023 the assumed and deferred length declarations may be written in this style:
character*(*) ... ! Assumed length
character*(:) ... ! Deferred length
character*(1023) ... ! For completeness
Well, what does "assumed length" mean?
For a dummy argument such as Name it's length is taken from the length of the actual argument of the procedure. With character :: Name*4 the argument is of length 4, regardless of the length of the argument to the subroutine (as long as it's of length at least 4). When the dummy is of assumed length it is of length 12 if the argument is of length 12, and so on.
Although not in the question, a character named constant may also assume its length from the defining expression:
character*(*), parameter :: label='This long'
Deferred length is left to other questions.
I need a program to convert from base a to base b, where base a and b could be from 2 to 36.
My idea was to use strings as the numbers, convert to base 10 as an intermediary and then convert from base 10 to base b. As I'm new on Fortran I can't understand quite the functions and substring, right now I'm getting the error:
intToChar = cadena(int,int)
1
Error: Unclassifiable statement at (1)
On the next code:
CHARACTER FUNCTION intToChar(int)
IMPLICIT NONE
INTEGER, INTENT(IN) :: int
CHARACTER(LEN = 36) :: cadena
cadena = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
intToChar = cadena(int,int)
END FUNCTION intToChar
I'm following this tutorial
The syntax to select a substring from a character variable uses a colon :, not a comma ,. The line the compiler is complaining about should be:
intToChar = cadena(int:int)
This will select the single character as position int from cadena, which appears to be your goal with that function.