<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Converting c-string to Fortran string in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959515#M94338</link>
    <description>&lt;P&gt;In the brave new world of c interoperability the standard requires that c-strings passed into a Fortran subroutine are interpreted as arrays of characters of length 1. So to use them in a Fortran program and array of characters has to be converted into a character string. So my question is what is the best way of doing this? At the moment I'm using the function below with example usage but I'm not convinced it is optimal. Thanks.&lt;/P&gt;
&lt;P&gt;[fortran]&lt;/P&gt;
&lt;P&gt;module cstr&lt;BR /&gt;&lt;BR /&gt;contains&lt;BR /&gt;&lt;BR /&gt;function c_to_f_string(s) result(str)&lt;BR /&gt;&amp;nbsp; use iso_c_binding&lt;BR /&gt;&amp;nbsp; character(kind=c_char,len=1), intent(in) :: s(*)&lt;BR /&gt;&amp;nbsp; character(len=:), allocatable :: str&lt;BR /&gt;&amp;nbsp; integer i, nchars&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; i = 1&lt;BR /&gt;&amp;nbsp; do&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s(i) == c_null_char) exit&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;BR /&gt;&amp;nbsp; end do&lt;BR /&gt;&amp;nbsp; nchars = i - 1&amp;nbsp; ! Exclude null character from Fortran string&lt;BR /&gt;&amp;nbsp; allocate(character(len=nchars) :: str)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; str = transfer(s(1:nchars), str)&lt;BR /&gt;&lt;BR /&gt;end function c_to_f_string&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;subroutine pstr(s) bind(c,name='pstr')&lt;BR /&gt;&amp;nbsp; use iso_c_binding&lt;BR /&gt;&amp;nbsp; use cstr&lt;BR /&gt;&amp;nbsp; character(kind=c_char,len=1), intent(in) :: s(*)&lt;BR /&gt;&amp;nbsp; character(len=:), allocatable :: str&lt;BR /&gt;&amp;nbsp; integer i, nchars&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; write(*,'(a)') c_to_f_string(s)&lt;BR /&gt;&lt;BR /&gt;end subroutine pstr&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;[/fortran]&lt;/P&gt;
&lt;P&gt;[cpp]&lt;/P&gt;
&lt;P&gt;extern "C" {&lt;BR /&gt;&amp;nbsp; void pstr(const char*);&lt;BR /&gt;};&lt;BR /&gt;&lt;BR /&gt;int main(int argc, char** argv) {&lt;BR /&gt;&amp;nbsp; if (argc &amp;gt; 1) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pstr(argv[1]);&lt;BR /&gt;&amp;nbsp; } else {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pstr("hello");&lt;BR /&gt;&amp;nbsp; }&lt;BR /&gt;&amp;nbsp; return 0;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;[/cpp]&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;</description>
    <pubDate>Mon, 13 May 2013 09:59:00 GMT</pubDate>
    <dc:creator>Simon_Geard</dc:creator>
    <dc:date>2013-05-13T09:59:00Z</dc:date>
    <item>
      <title>Converting c-string to Fortran string</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959515#M94338</link>
      <description>&lt;P&gt;In the brave new world of c interoperability the standard requires that c-strings passed into a Fortran subroutine are interpreted as arrays of characters of length 1. So to use them in a Fortran program and array of characters has to be converted into a character string. So my question is what is the best way of doing this? At the moment I'm using the function below with example usage but I'm not convinced it is optimal. Thanks.&lt;/P&gt;
&lt;P&gt;[fortran]&lt;/P&gt;
&lt;P&gt;module cstr&lt;BR /&gt;&lt;BR /&gt;contains&lt;BR /&gt;&lt;BR /&gt;function c_to_f_string(s) result(str)&lt;BR /&gt;&amp;nbsp; use iso_c_binding&lt;BR /&gt;&amp;nbsp; character(kind=c_char,len=1), intent(in) :: s(*)&lt;BR /&gt;&amp;nbsp; character(len=:), allocatable :: str&lt;BR /&gt;&amp;nbsp; integer i, nchars&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; i = 1&lt;BR /&gt;&amp;nbsp; do&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s(i) == c_null_char) exit&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;BR /&gt;&amp;nbsp; end do&lt;BR /&gt;&amp;nbsp; nchars = i - 1&amp;nbsp; ! Exclude null character from Fortran string&lt;BR /&gt;&amp;nbsp; allocate(character(len=nchars) :: str)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; str = transfer(s(1:nchars), str)&lt;BR /&gt;&lt;BR /&gt;end function c_to_f_string&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;subroutine pstr(s) bind(c,name='pstr')&lt;BR /&gt;&amp;nbsp; use iso_c_binding&lt;BR /&gt;&amp;nbsp; use cstr&lt;BR /&gt;&amp;nbsp; character(kind=c_char,len=1), intent(in) :: s(*)&lt;BR /&gt;&amp;nbsp; character(len=:), allocatable :: str&lt;BR /&gt;&amp;nbsp; integer i, nchars&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; write(*,'(a)') c_to_f_string(s)&lt;BR /&gt;&lt;BR /&gt;end subroutine pstr&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;[/fortran]&lt;/P&gt;
&lt;P&gt;[cpp]&lt;/P&gt;
&lt;P&gt;extern "C" {&lt;BR /&gt;&amp;nbsp; void pstr(const char*);&lt;BR /&gt;};&lt;BR /&gt;&lt;BR /&gt;int main(int argc, char** argv) {&lt;BR /&gt;&amp;nbsp; if (argc &amp;gt; 1) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pstr(argv[1]);&lt;BR /&gt;&amp;nbsp; } else {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pstr("hello");&lt;BR /&gt;&amp;nbsp; }&lt;BR /&gt;&amp;nbsp; return 0;&lt;BR /&gt;}&lt;/P&gt;
&lt;P&gt;[/cpp]&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 13 May 2013 09:59:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959515#M94338</guid>
      <dc:creator>Simon_Geard</dc:creator>
      <dc:date>2013-05-13T09:59:00Z</dc:date>
    </item>
    <item>
      <title>If "optimal" can be related</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959516#M94339</link>
      <description>&lt;P&gt;If "optimal" can be related to "less obscure," why not study several examples you would find in web search or in textbooks?&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www-01.ibm.com/support/docview.wss?uid=swg1LI72736" target="_blank"&gt;http://www-01.ibm.com/support/docview.wss?uid=swg1LI72736&lt;/A&gt; is a posted example of direct interoperation between C and Fortran strings according to standard, where there seems little point nowadays in avoiding acknowledged analysis bugs of early compilers.&lt;/P&gt;
&lt;P&gt;I suppose the index intrinsic might be used to make a Fortran equivalent of C strnlen.&lt;/P&gt;</description>
      <pubDate>Mon, 13 May 2013 11:36:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959516#M94339</guid>
      <dc:creator>TimP</dc:creator>
      <dc:date>2013-05-13T11:36:00Z</dc:date>
    </item>
    <item>
      <title>Sorry but I don't understand</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959517#M94340</link>
      <description>&lt;P&gt;Sorry but I don't understand what you're saying. The code I posted has nothing to do with avoiding compiler bugs and is certainly not obscure. The code to which you refer does not convert a c-string to a fortran string. By optimal I meant efficient and, possibly, compact. For example when it is implemented the &lt;EM&gt;findloc&lt;/EM&gt; function could be used to locate the &lt;EM&gt;c_null_char&lt;/EM&gt; and I would expect that to be at least as efficient as the&amp;nbsp;&lt;EM&gt;do&lt;/EM&gt; loop in my implementation. I'm using&amp;nbsp;&lt;EM&gt;transfer&lt;/EM&gt; but perhaps it would be more efficient to use a&amp;nbsp;&lt;EM&gt;do&lt;/EM&gt; loop. Perhaps there is an Intel intrinsic that does the job, something like QQCTOFSTR.&lt;/P&gt;</description>
      <pubDate>Mon, 13 May 2013 12:14:09 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959517#M94340</guid>
      <dc:creator>Simon_Geard</dc:creator>
      <dc:date>2013-05-13T12:14:09Z</dc:date>
    </item>
    <item>
      <title>I've wondered about this to. </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959518#M94341</link>
      <description>&lt;P&gt;I've wondered about this to.&amp;nbsp; What you've got looks ok to me. Observations that aren't particularly significant, and note I've never bothered to measure performance or look at generated assembly, etc:&lt;/P&gt;
&lt;P&gt;- I tend to use FORALL or a DO loop around an assignment to explicitly copy the array across to the scalar - transfer like you do might be more efficient, but using transfer always makes me twitchy.&amp;nbsp; Plus one day you might use a processor where C_CHAR /= KIND('a'), and use of transfer would break silently in that situation.&amp;nbsp; Assignment at least gives you some character set conversion guarantees.&lt;/P&gt;
&lt;P&gt;- It would have been nice if C_TO_F_STRING (perhaps with a CHARACTER(:) pointer on the fortran side) was part of ISO_C_BINDING.&amp;nbsp; Perhaps one day it might be - and if so there's a reasonable chance that a name like that would be used.&amp;nbsp; If they do add a function of that name to the intrinsic module, your `USE iso_c_binding` statement is going to cause dramas.&amp;nbsp; Consequently I always qualify my use of intrinsic modules with ONLY.&lt;/P&gt;
&lt;P&gt;- I tend to cheat a bit and use the C library variant of strlen rather than writing out an explicit loop.&amp;nbsp; That's partly motivated by delusions on my part that some C library programmer has spent months writing hand tuned assembly in order to do strlen efficiently.&lt;/P&gt;
&lt;P&gt;- You forgot implicit none.&lt;/P&gt;
&lt;P&gt;Something akin to what I use (slightly different starting point of a C_PTR versus a character array, but the approaches become equivalent) is&amp;nbsp;&lt;A href="http://stackoverflow.com/a/11443635/1234550"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Another option I've mucked around with is to avoid a copy using Fortran pointers.&amp;nbsp; The lifetime of the fortran pointer is then restricted by the life of the corresponding C object.&amp;nbsp; Perhaps:&lt;/P&gt;
&lt;P&gt;[fortran]&lt;/P&gt;
&lt;P&gt;MODULE c_f_string_ptr&lt;BR /&gt;&amp;nbsp; IMPLICIT NONE&lt;BR /&gt;&amp;nbsp; PRIVATE&lt;BR /&gt;&amp;nbsp; PUBLIC :: C_F_STRING&lt;BR /&gt;CONTAINS&lt;BR /&gt;&amp;nbsp; FUNCTION C_F_STRING(c_str) RESULT(f_str)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_CHAR&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TYPE(C_PTR), INTENT(IN) :: c_str&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHARACTER(:,KIND=C_CHAR), POINTER :: f_str&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHARACTER(KIND=C_CHAR), POINTER :: arr(:)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; INTERFACE&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ! Steal std C library function rather than writing our own.&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FUNCTION strlen(s) BIND(C, NAME='strlen')&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_SIZE_T&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IMPLICIT NONE&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; !----&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TYPE(C_PTR), INTENT(IN), VALUE :: s&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INTEGER(C_SIZE_T) :: strlen&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END FUNCTION strlen&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END INTERFACE&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; !****&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CALL C_F_POINTER(c_str, arr, [strlen(c_str)])&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CALL get_scalar_pointer(SIZE(arr), arr, f_str)&lt;BR /&gt;&amp;nbsp; END FUNCTION C_F_STRING&lt;BR /&gt;&amp;nbsp; SUBROUTINE get_scalar_pointer(scalar_len, scalar, ptr)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_CHAR&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; INTEGER, INTENT(IN) :: scalar_len&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHARACTER(KIND=C_CHAR,LEN=scalar_len), INTENT(IN), TARGET :: scalar(1)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHARACTER(:,KIND=C_CHAR), INTENT(OUT), POINTER :: ptr&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; !***&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ptr =&amp;gt; scalar(1)&lt;BR /&gt;&amp;nbsp; END SUBROUTINE get_scalar_pointer&lt;BR /&gt;END MODULE c_f_string_ptr&lt;BR /&gt;&lt;BR /&gt;[/fortran]&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 13 May 2013 12:36:11 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959518#M94341</guid>
      <dc:creator>IanH</dc:creator>
      <dc:date>2013-05-13T12:36:11Z</dc:date>
    </item>
    <item>
      <title>Maybe I´m doing this</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959519#M94342</link>
      <description>&lt;P&gt;Maybe I´m doing this completely wrong, but I use this method for data exchange between C# and Fortran via a C++ wrapper:&lt;/P&gt;
&lt;P&gt;[cpp]&lt;BR /&gt;extern "C" int INPUT(const char*, int*);&lt;BR /&gt;int openProjectFile(const char* filename)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; int lenFilename = sizeof(filename);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; return INPUT(filename, &amp;amp;lenFilename);&lt;BR /&gt;}[/cpp]&lt;/P&gt;
&lt;P&gt;[fortran]&lt;BR /&gt;integer(kind=4) function input(originalFilename)&lt;BR /&gt;implicit none&lt;BR /&gt;character*255 Filename, originalFilename&lt;BR /&gt;write(filename,'(a)') originalFilename&lt;BR /&gt;call cutChar0(filename) ! a subroutine that remove the char(0) from filename&lt;BR /&gt;input = 0&lt;BR /&gt;! some code where input is being altered when there is an error&lt;BR /&gt;end function input[/fortran]&lt;/P&gt;
&lt;P&gt;In my C# program I can pass a string to openProjectFile. Of course it couldn´t be longer than 255 characters. I haven´t had problems with this approach.&lt;/P&gt;
&lt;P&gt;Markus&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 14 May 2013 07:41:10 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959519#M94342</guid>
      <dc:creator>onkelhotte</dc:creator>
      <dc:date>2013-05-14T07:41:10Z</dc:date>
    </item>
    <item>
      <title>Thank you very much. I hadn't</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959520#M94343</link>
      <description>&lt;P&gt;Thank you very much. I hadn't thought of using strlen - an interesting idea!&lt;/P&gt;</description>
      <pubDate>Tue, 14 May 2013 08:23:34 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Converting-c-string-to-Fortran-string/m-p/959520#M94343</guid>
      <dc:creator>Simon_Geard</dc:creator>
      <dc:date>2013-05-14T08:23:34Z</dc:date>
    </item>
  </channel>
</rss>

