Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #104752 > unrolled thread

writing a c program to substitute text

Started byfred flintstone <fred@server.invalid>
First post2017-02-26 04:14 -0800
Last post2017-02-28 08:46 -0800
Articles 20 on this page of 86 — 21 participants

Back to article view | Back to comp.lang.c


Contents

  writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-26 04:14 -0800
    Re: writing a c program to substitute text fir <profesor.fir@gmail.com> - 2017-02-26 04:55 -0800
    Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-26 14:28 +0100
      Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-27 03:58 -0800
        Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-27 13:11 +0000
          Re: writing a c program to substitute text BartC <bc@freeuk.com> - 2017-02-27 13:33 +0000
            Re: writing a c program to substitute text scott@slp53.sl.home (Scott Lurndal) - 2017-02-27 17:12 +0000
              Re: writing a c program to substitute text BartC <bc@freeuk.com> - 2017-02-27 17:59 +0000
                Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 19:05 +0100
                Re: writing a c program to substitute text scott@slp53.sl.home (Scott Lurndal) - 2017-02-27 18:37 +0000
                  Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-27 11:40 -0800
          Re: writing a c program to substitute text Manfred <noname@invalid.add> - 2017-02-27 16:03 +0100
          Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-01 05:33 -0800
            Re: writing a c program to substitute text "D. Aaron Sawyer" <aaron@110.net> - 2017-03-01 10:32 -0400
              Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-01 06:59 -0800
                Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-01 15:24 +0000
                  Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-02 01:47 -0800
                    Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-02 11:05 +0000
        Re: writing a c program to substitute text jt@toerring.de (Jens Thoms Toerring) - 2017-02-27 13:33 +0000
          Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-27 09:10 -0800
            Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 19:07 +0100
              Re: writing a c program to substitute text jt@toerring.de (Jens Thoms Toerring) - 2017-02-27 18:23 +0000
        Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 14:46 +0100
          Re: writing a c program to substitute text James Kuyper <jameskuyper@verizon.net> - 2017-02-27 09:27 -0500
            Re: writing a c program to substitute text GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-27 15:28 +0100
              Re: writing a c program to substitute text James Kuyper <jameskuyper@verizon.net> - 2017-02-27 09:38 -0500
            Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 15:44 +0100
              Re: writing a c program to substitute text James Kuyper <jameskuyper@verizon.net> - 2017-02-27 10:36 -0500
              Re: writing a c program to substitute text Anglican <h.toms@qmul.ac.uk> - 2017-02-27 15:50 +0000
                Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 17:13 +0100
                Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-27 16:30 -0800
            Re: writing a c program to substitute text fir <profesor.fir@gmail.com> - 2017-02-27 07:08 -0800
              Re: writing a c program to substitute text fir <profesor.fir@gmail.com> - 2017-02-27 07:20 -0800
                Re: writing a c program to substitute text fir <profesor.fir@gmail.com> - 2017-02-27 07:24 -0800
          Re: writing a c program to substitute text Manfred <noname@invalid.add> - 2017-02-27 16:00 +0100
          Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-27 09:22 -0800
            Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 19:11 +0100
        Re: writing a c program to substitute text John Bode <jfbode1029@gmail.com> - 2017-02-28 15:41 -0800
          solved Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-02 01:25 -0800
            Re: solved Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-03-02 11:28 +0100
            Re: solved Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-02 10:54 +0000
              Re: solved Re: writing a c program to substitute text Manfred <noname@invalid.add> - 2017-03-02 15:28 +0100
                Re: solved Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-02 14:51 +0000
              Re: solved Re: writing a c program to substitute text John Bode <jfbode1029@gmail.com> - 2017-03-02 14:18 -0800
                Re: solved Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-02 23:55 +0000
                  Re: solved Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-14 18:32 -0700
          Re: writing a c program to substitute text Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-17 07:04 -0700
      Re: writing a c program to substitute text jladasky@itu.edu - 2017-02-27 13:48 -0800
        Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-27 14:16 -0800
          Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 08:47 +0100
            Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-28 01:59 -0800
              Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 11:39 +0100
              Re: writing a c program to substitute text Richard Heathfield <rjh@cpax.org.uk> - 2017-02-28 12:03 +0000
                Re: writing a c program to substitute text BartC <bc@freeuk.com> - 2017-02-28 13:33 +0000
                  Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 14:43 +0100
                    Re: writing a c program to substitute text BartC <bc@freeuk.com> - 2017-02-28 13:59 +0000
                      Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-03-01 04:26 -0800
        Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 23:29 +0100
        Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-27 15:10 -0800
    Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-26 06:42 -0800
      Re: writing a c program to substitute text Richard Heathfield <rjh@cpax.org.uk> - 2017-02-26 16:54 +0000
        [OT] "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2017-02-27 00:56 +0800
      Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-26 13:36 -0800
        Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-26 14:53 -0800
          Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 00:53 +0100
            Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-26 17:30 -0800
              Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-26 17:44 -0800
              Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-27 01:46 +0000
                Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 09:29 +0100
                  Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-27 02:12 -0800
                    Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-27 13:11 +0100
      Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-27 04:41 -0800
        Re: writing a c program to substitute text Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-02-27 05:04 -0800
          Re: writing a c program to substitute text Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-27 13:25 +0000
          Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-27 09:56 -0800
    Re: writing a c program to substitute text "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2017-02-27 01:00 +0800
    Re: writing a c program to substitute text "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-26 18:55 -0500
      Re: writing a c program to substitute text fred flintstone <fred@server.invalid> - 2017-02-28 04:20 -0800
        Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 14:38 +0100
          Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-28 08:33 -0800
            Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 19:38 +0100
              Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-28 11:40 -0800
                Re: writing a c program to substitute text David Brown <david.brown@hesbynett.no> - 2017-02-28 21:03 +0100
              Re: gcc optimization levels Noob <root@127.0.0.1> - 2017-02-28 22:55 +0100
        Re: writing a c program to substitute text "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-28 11:43 -0500
        Re: writing a c program to substitute text Keith Thompson <kst-u@mib.org> - 2017-02-28 08:46 -0800

Page 1 of 5  [1] 2 3 4 5  Next page →


#104752 — writing a c program to substitute text

Fromfred flintstone <fred@server.invalid>
Date2017-02-26 04:14 -0800
Subjectwriting a c program to substitute text
Message-ID<ehfv4oFu00sU1@mid.individual.net>
Hello ng,

Usually, I cruise through clc on the way to somewhere else, but I've 
spent so long reconstituting my c capabilities that I want to acquire a 
few more before I focus on perl. In the perl world, I'm still working 
through the material of _Intermediate Perl_, but it forces the serious 
student to get involved in the world of github, packages, and the 50% I 
haven't done yet. That can rest for the moment.

Instead I seek something that is right on the kingpin for topicality in 
clc. Here is the text file I want to substitute into:

echo 'after preprocessor your program is' >text3.txt
gcc  -E  arrow.c >>text3.txt
echo 'after compilation avec warnings, output is' >>text3.txt
gcc -Wall -Wextra -o arrow arrow.c >>text3.txt
./arrow >>text3.txt
echo 'source listing is' >>text3.txt
cat arrow.c >>text3.txt

So there's 3DBESNUB type things that a gonzaga-beating cougar will do in 
terms of general problem solving or even forensic problem-solving. Right 
at the top is that I don't know how to declare strings in c in a safe way.

Let's say that you're hard-coding a string between single quotes, for 
example:

'arrow'

, how do I declare this string to exist safely?

Do I malloc a 1000 because someone has to make an adult decision?
-- 
fred flintstone

[toc] | [next] | [standalone]


#104755

Fromfir <profesor.fir@gmail.com>
Date2017-02-26 04:55 -0800
Message-ID<a3655dcb-d431-4e5f-a6cc-618928eefd6f@googlegroups.com>
In reply to#104752
W dniu niedziela, 26 lutego 2017 13:14:23 UTC+1 użytkownik fred flintstone napisał:
> Hello ng,
> 
> Usually, I cruise through clc on the way to somewhere else, but I've 
> spent so long reconstituting my c capabilities that I want to acquire a 
> few more before I focus on perl. In the perl world, I'm still working 
> through the material of _Intermediate Perl_, but it forces the serious 
> student to get involved in the world of github, packages, and the 50% I 
> haven't done yet. That can rest for the moment.
> 
> Instead I seek something that is right on the kingpin for topicality in 
> clc. Here is the text file I want to substitute into:
> 
> echo 'after preprocessor your program is' >text3.txt
> gcc  -E  arrow.c >>text3.txt
> echo 'after compilation avec warnings, output is' >>text3.txt
> gcc -Wall -Wextra -o arrow arrow.c >>text3.txt
> ./arrow >>text3.txt
> echo 'source listing is' >>text3.txt
> cat arrow.c >>text3.txt
> 
> So there's 3DBESNUB type things that a gonzaga-beating cougar will do in 
> terms of general problem solving or even forensic problem-solving. Right 
> at the top is that I don't know how to declare strings in c in a safe way.
> 
> Let's say that you're hard-coding a string between single quotes, for 
> example:
> 
> 'arrow'
> 
> , how do I declare this string to exist safely?
> 

c is not safe it is dangerous;c, it is something like skateboarding and we c people like it

besides if you use

char* s = "arrow";

it isnt insanely 'unsafe' 

> Do I malloc a 1000 because someone has to make an adult decision?
> -- 
> fred flintstone

[toc] | [prev] | [next] | [standalone]


#104758

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-26 14:28 +0100
Message-ID<o8ul21$ip3$1@dont-email.me>
In reply to#104752
On 26/02/17 13:14, fred flintstone wrote:
> Hello ng,
>
> Usually, I cruise through clc on the way to somewhere else, but I've
> spent so long reconstituting my c capabilities that I want to acquire a
> few more before I focus on perl. In the perl world, I'm still working
> through the material of _Intermediate Perl_, but it forces the serious
> student to get involved in the world of github, packages, and the 50% I
> haven't done yet. That can rest for the moment.
>
> Instead I seek something that is right on the kingpin for topicality in
> clc. Here is the text file I want to substitute into:
>
> echo 'after preprocessor your program is' >text3.txt
> gcc  -E  arrow.c >>text3.txt
> echo 'after compilation avec warnings, output is' >>text3.txt
> gcc -Wall -Wextra -o arrow arrow.c >>text3.txt
> ./arrow >>text3.txt
> echo 'source listing is' >>text3.txt
> cat arrow.c >>text3.txt
>
> So there's 3DBESNUB type things that a gonzaga-beating cougar will do in
> terms of general problem solving or even forensic problem-solving. Right
> at the top is that I don't know how to declare strings in c in a safe way.
>
> Let's say that you're hard-coding a string between single quotes, for
> example:
>
> 'arrow'
>
> , how do I declare this string to exist safely?
>
> Do I malloc a 1000 because someone has to make an adult decision?

I cannot fathom what you are trying to say or do here.  I know fine what 
the commands above do, but don't understand why - nor does "3DBESNUB 
type things" or "gonzaga-beating cougar" make any sense.

In C, strings are between double quotes, not single quotes (they are for 
character literals).  Writing something like

	const char *s = "Arrow";

is perfectly safe.

If you have a C question to ask, feel free and many people here will try 
to answer it.  But please, make it comprehensible and say what you are 
actually trying to do - it makes it a lot easier to help.  Perhaps give 
an example of the code you are trying to write, and then say where you 
are having trouble.

[toc] | [prev] | [next] | [standalone]


#104841

Fromfred flintstone <fred@server.invalid>
Date2017-02-27 03:58 -0800
Message-ID<ehiij4Ffgn1U1@mid.individual.net>
In reply to#104758
On 02/26/2017 05:28 AM, David Brown wrote:

>
> I cannot fathom what you are trying to say or do here.  I know fine what
> the commands above do, but don't understand why - nor does "3DBESNUB
> type things" or "gonzaga-beating cougar" make any sense.
>
> In C, strings are between double quotes, not single quotes (they are for
> character literals).  Writing something like
>
>     const char *s = "Arrow";
>
> is perfectly safe.
>
> If you have a C question to ask, feel free and many people here will try
> to answer it.  But please, make it comprehensible and say what you are
> actually trying to do - it makes it a lot easier to help.  Perhaps give
> an example of the code you are trying to write, and then say where you
> are having trouble.
>

As James Kuyper correctly links downthread, 3DBESNUB was the 
problem-solving acronym that my entire cohort at BYU had to use to get 
full credit on any physics problem. The first three letters are for 
diagrams, but they are in short supply in usenet.

It seems I need code to describe the type of code I want. I honestly 
thought I had to come up with a number that wouldn't be smaller in bytes 
than whatever I'm storing in a string.

Let me cough up some source and address a specification:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int version;
    int c;
    FILE *fptr, *gptr;
    const char *executable1 = "arrow";
    const char *executable2 = "mahershala";
    const char *base = "toolchain";
    const char *ext = "sh";
    fptr = fopen("toolchain3.sh","r");

    if(fptr == NULL)
    {
       printf("fopen no bueno");
       exit(1);
    }
    gptr = fopen("toolchain4.sh","w");

    if(gptr == NULL)
    {
       printf("gopen no bueno");
       exit(1);
    }

       while (1) {
       c = fgetc(fptr);

       if (c == EOF)
          break;
       else
          putc(c, gptr);
    }


    fclose(fptr);
    fclose(gptr);

    return 0;
}

I need to concatenate 'toolchain3.sh' from its constituent parts and 
then increment it as the filename of gptr.

This lacks the logic for a substitution but sets the stage for it. In 
the newly-created .sh file, executable2 shall be substituted for 
executable1. Again, for reference, this is our file:

echo 'after preprocessor your program is' >text3.txt
gcc  -E  arrow.c >>text3.txt
echo 'after compilation avec warnings, output is' >>text3.txt
gcc -Wall -Wextra -o arrow arrow.c >>text3.txt
./arrow >>text3.txt
echo 'source listing is' >>text3.txt
cat arrow.c >>text3.txt

Also, I need a way of determining the natural number that follows 
'text'. This is to be substituted by the number appending 'toolchain', 
so that the new number is uniform.

Alright, I hope I am clearer now. The BYU cougars did beat undefeated 
Gonzaga in college hoops. It was a news event and this is a newsgroup, 
where we do a lot of talking about C. It's also basketball season.

How important are substitutions, especially when they are errant? Did 
you watch the Oscars?
--
fred flintstone

[toc] | [prev] | [next] | [standalone]


#104847

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-27 13:11 +0000
Message-ID<87a897u6b2.fsf@bsb.me.uk>
In reply to#104841
fred flintstone <fred@server.invalid> writes:
<snip>
> I need to concatenate 'toolchain3.sh' from its constituent parts and
> then increment it as the filename of gptr.

That's not too hard, but it's much more fiddly in C than in any
scripting language I can think of.  Why do you want to do this in C?
The kind of things you hint at doing elsewhere in your post are trivial
in any of the many scripting languages you have available.

Anyway, here's one way:

     int vnum = 3;
     const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
     char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
     int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);

Repeat after vnum += 1;.  Whether this is suitable (it's C99) depends in
part on why you using C.

<snip>
(Your posts will get more helpful replies if they are short and to the
point.)
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#104850

FromBartC <bc@freeuk.com>
Date2017-02-27 13:33 +0000
Message-ID<o919n1$ne5$1@dont-email.me>
In reply to#104847
On 27/02/2017 13:11, Ben Bacarisse wrote:
> fred flintstone <fred@server.invalid> writes:
> <snip>
>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>> then increment it as the filename of gptr.
>
> That's not too hard, but it's much more fiddly in C than in any
> scripting language I can think of.  Why do you want to do this in C?
> The kind of things you hint at doing elsewhere in your post are trivial
> in any of the many scripting languages you have available.
>
> Anyway, here's one way:
>
>      int vnum = 3;
>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);

Here's pretty much the same thing but without a VLA, nor the weird thing 
with putting an snprintf call inside the array bounds.

But it needs an upper limit for the filename length to be set. The part 
calling 'getfilename' will have an idea of what is reasonable, in this 
case it has to accommadate 'toolchainN.sh' where N, because I've made it 
an int, might have 10 or 11 digits. So 300 is plenty.

---------------------------------------

#include <stdio.h>

void getfilename(char* dest, int destsize,
                  char* basefile, int index, char* extension) {
     snprintf(dest,destsize, "%s%d.%s", basefile, index, extension);
}

int main(void) {
     char filename[300];
     int i;

     for (i=1; i<=10; ++i) {
         getfilename(filename, sizeof filename, "toolchain",i,"sh");
         puts(filename);
     }
}


-- 
bartc

[toc] | [prev] | [next] | [standalone]


#104894

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-02-27 17:12 +0000
Message-ID<S5ZsA.41331$Wp.6174@fx34.iad>
In reply to#104850
BartC <bc@freeuk.com> writes:
>On 27/02/2017 13:11, Ben Bacarisse wrote:
>> fred flintstone <fred@server.invalid> writes:
>> <snip>
>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>> then increment it as the filename of gptr.
>>
>> That's not too hard, but it's much more fiddly in C than in any
>> scripting language I can think of.  Why do you want to do this in C?
>> The kind of things you hint at doing elsewhere in your post are trivial
>> in any of the many scripting languages you have available.
>>
>> Anyway, here's one way:
>>
>>      int vnum = 3;
>>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>
>Here's pretty much the same thing but without a VLA, nor the weird thing 
>with putting an snprintf call inside the array bounds.

That weird thing ensures that 'name1' is allocated enough
memory to hold the entire string.

>
>But it needs an upper limit for the filename length to be set. The part 
>calling 'getfilename' will have an idea of what is reasonable, in this 
>case it has to accommadate 'toolchainN.sh' where N, because I've made it 
>an int, might have 10 or 11 digits. So 300 is plenty.

Until someone moves it to a deeply nested home directory with a
512 byte path prefix.

>
>---------------------------------------
>
>#include <stdio.h>
>
>void getfilename(char* dest, int destsize,

the second argument to snprintf is a size_t, sizeof returns
a size_t, thus 'destsize' should be declared as a size_t.

>                  char* basefile, int index, char* extension)

basefile and extension should be declared as const.  And, if
'N' in your filename should be a positive value, make index
unsigned and use '%u' in the format string.

[toc] | [prev] | [next] | [standalone]


#104900

FromBartC <bc@freeuk.com>
Date2017-02-27 17:59 +0000
Message-ID<o91pa4$kt4$1@dont-email.me>
In reply to#104894
On 27/02/2017 17:12, Scott Lurndal wrote:
> BartC <bc@freeuk.com> writes:
>> On 27/02/2017 13:11, Ben Bacarisse wrote:
>>> fred flintstone <fred@server.invalid> writes:
>>> <snip>
>>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>>> then increment it as the filename of gptr.
>>>
>>> That's not too hard, but it's much more fiddly in C than in any
>>> scripting language I can think of.  Why do you want to do this in C?
>>> The kind of things you hint at doing elsewhere in your post are trivial
>>> in any of the many scripting languages you have available.
>>>
>>> Anyway, here's one way:
>>>
>>>      int vnum = 3;
>>>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>>
>> Here's pretty much the same thing but without a VLA, nor the weird thing
>> with putting an snprintf call inside the array bounds.
>
> That weird thing ensures that 'name1' is allocated enough
> memory to hold the entire string.

But requiring two passes.

>>
>> But it needs an upper limit for the filename length to be set. The part
>> calling 'getfilename' will have an idea of what is reasonable, in this
>> case it has to accommadate 'toolchainN.sh' where N, because I've made it
>> an int, might have 10 or 11 digits. So 300 is plenty.
>
> Until someone moves it to a deeply nested home directory with a
> 512 byte path prefix.

That will be the same problem with the VLA code. Unless 'base' points to 
that long path. But since it is a constant string, you will know it is a 
long string and can adjust the buffer size accordingly.

Otherwise you're relying on a language feature that may not generally be 
available.

Or you could use a much larger string buffer (eg 4K or 16K). If someone 
is actually using 16000-character path lengths, then they've got bigger 
problems, like knowing how to use paths sensibly, and understanding the 
difference between the title of a file, and its contents; usually the 
former is shorter than the latter.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#104903

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-27 19:05 +0100
Message-ID<o91plo$ld3$1@dont-email.me>
In reply to#104900
On 27/02/17 18:59, BartC wrote:
> On 27/02/2017 17:12, Scott Lurndal wrote:
>> BartC <bc@freeuk.com> writes:
>>> On 27/02/2017 13:11, Ben Bacarisse wrote:
>>>> fred flintstone <fred@server.invalid> writes:
>>>> <snip>
>>>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>>>> then increment it as the filename of gptr.
>>>>
>>>> That's not too hard, but it's much more fiddly in C than in any
>>>> scripting language I can think of.  Why do you want to do this in C?
>>>> The kind of things you hint at doing elsewhere in your post are trivial
>>>> in any of the many scripting languages you have available.
>>>>
>>>> Anyway, here's one way:
>>>>
>>>>      int vnum = 3;
>>>>      const char *base = "toolchain", *ext = "sh", *name_fmt =
>>>> "%s%d.%s";
>>>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>>>
>>> Here's pretty much the same thing but without a VLA, nor the weird thing
>>> with putting an snprintf call inside the array bounds.
>>
>> That weird thing ensures that 'name1' is allocated enough
>> memory to hold the entire string.
>
> But requiring two passes.
>

That's life.  You don't (in general) know how long a calculated string 
will be until you have calculated it.  Your choices are to calculate it 
exactly (like this), allocate space larger than you could reasonably 
expect (like you suggest), or combine the methods - allocate a large 
space first, and if that turns out to be too small, allocate the 
required size and re-do the snprintf.

Languages which have strings as a part of the language do the same - 
they just hide the messy details.  (This is, of course, one of the key 
reasons that C is a poor choice if your program involves a lot of string 
work.)

>>>
>>> But it needs an upper limit for the filename length to be set. The part
>>> calling 'getfilename' will have an idea of what is reasonable, in this
>>> case it has to accommadate 'toolchainN.sh' where N, because I've made it
>>> an int, might have 10 or 11 digits. So 300 is plenty.
>>
>> Until someone moves it to a deeply nested home directory with a
>> 512 byte path prefix.
>
> That will be the same problem with the VLA code. Unless 'base' points to
> that long path. But since it is a constant string, you will know it is a
> long string and can adjust the buffer size accordingly.
>
> Otherwise you're relying on a language feature that may not generally be
> available.
>
> Or you could use a much larger string buffer (eg 4K or 16K). If someone
> is actually using 16000-character path lengths, then they've got bigger
> problems, like knowing how to use paths sensibly, and understanding the
> difference between the title of a file, and its contents; usually the
> former is shorter than the latter.
>

[toc] | [prev] | [next] | [standalone]


#104913

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-02-27 18:37 +0000
Message-ID<Nl_sA.69741$EN2.32732@fx44.iad>
In reply to#104900
BartC <bc@freeuk.com> writes:
>On 27/02/2017 17:12, Scott Lurndal wrote:
>> BartC <bc@freeuk.com> writes:
>>> On 27/02/2017 13:11, Ben Bacarisse wrote:
>>>> fred flintstone <fred@server.invalid> writes:
>>>> <snip>
>>>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>>>> then increment it as the filename of gptr.
>>>>
>>>> That's not too hard, but it's much more fiddly in C than in any
>>>> scripting language I can think of.  Why do you want to do this in C?
>>>> The kind of things you hint at doing elsewhere in your post are trivial
>>>> in any of the many scripting languages you have available.
>>>>
>>>> Anyway, here's one way:
>>>>
>>>>      int vnum = 3;
>>>>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>>>
>>> Here's pretty much the same thing but without a VLA, nor the weird thing
>>> with putting an snprintf call inside the array bounds.
>>
>> That weird thing ensures that 'name1' is allocated enough
>> memory to hold the entire string.
>
>But requiring two passes.

The nature of strings, in C, where there is no associated
length kept (contrast with counted ASCII or VAX-11 descriptors).

[toc] | [prev] | [next] | [standalone]


#104919

FromKeith Thompson <kst-u@mib.org>
Date2017-02-27 11:40 -0800
Message-ID<ln4lzffmnh.fsf@kst-u.example.com>
In reply to#104913
scott@slp53.sl.home (Scott Lurndal) writes:
> BartC <bc@freeuk.com> writes:
>>On 27/02/2017 17:12, Scott Lurndal wrote:
>>> BartC <bc@freeuk.com> writes:
[...]
>>>> Here's pretty much the same thing but without a VLA, nor the weird thing
>>>> with putting an snprintf call inside the array bounds.
>>>
>>> That weird thing ensures that 'name1' is allocated enough
>>> memory to hold the entire string.
>>
>>But requiring two passes.
>
> The nature of strings, in C, where there is no associated
> length kept (contrast with counted ASCII or VAX-11 descriptors).

Even with counted strings, you still have to allocate memory to hold the
characters.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#104863

FromManfred <noname@invalid.add>
Date2017-02-27 16:03 +0100
Message-ID<o91f3k$1di5$2@gioia.aioe.org>
In reply to#104847
On 2/27/2017 2:11 PM, Ben Bacarisse wrote:
> fred flintstone <fred@server.invalid> writes:
> <snip>
>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>> then increment it as the filename of gptr.
> That's not too hard, but it's much more fiddly in C than in any
> scripting language I can think of.  Why do you want to do this in C?
> The kind of things you hint at doing elsewhere in your post are trivial
> in any of the many scripting languages you have available.

Definitely true. Besides Perl, bash + sed come to mind. awk as well for 
the more experienced.

[toc] | [prev] | [next] | [standalone]


#105242

Fromfred flintstone <fred@server.invalid>
Date2017-03-01 05:33 -0800
Message-ID<eho0u5Fiia5U1@mid.individual.net>
In reply to#104847
On 02/27/2017 05:11 AM, Ben Bacarisse wrote:
> fred flintstone <fred@server.invalid> writes:
> <snip>
>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>> then increment it as the filename of gptr.
>
> That's not too hard, but it's much more fiddly in C than in any
> scripting language I can think of.  Why do you want to do this in C?
> The kind of things you hint at doing elsewhere in your post are trivial
> in any of the many scripting languages you have available.
>
> Anyway, here's one way:
>
>      int vnum = 3;
>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>
> Repeat after vnum += 1;.  Whether this is suitable (it's C99) depends in
> part on why you using C.

I'm having trouble with this, ben:

   int vnum, c, i;
   FILE *fptr, *gptr;



   vnum = 3;
   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);


   fptr = fopen (name1, "r");
   if (fptr == NULL) {
     printf ("fopen no bueno");
     exit (1);
   }
   vnum += 1;

   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int t = snprintf (name2, sizeof name1, name_fmt, base, vnum, ext);
   gptr = fopen (name2, "w");

   if (gptr == NULL) {
     printf ("gopen no bueno");
     exit (1);
   }
>
> <snip>
> (Your posts will get more helpful replies if they are short and to the
> point.)
>

Does the source itself announce what's wrong with it?
-- 
fred

[toc] | [prev] | [next] | [standalone]


#105251

From"D. Aaron Sawyer" <aaron@110.net>
Date2017-03-01 10:32 -0400
Message-ID<o96lts$bi$1@dont-email.me>
In reply to#105242
On 2017.03.01 09:33, fred flintstone wrote:
> On 02/27/2017 05:11 AM, Ben Bacarisse wrote:
>> fred flintstone <fred@server.invalid> writes:
>> <snip>
>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>> then increment it as the filename of gptr.
>>
>> That's not too hard, but it's much more fiddly in C than in any
>> scripting language I can think of.  Why do you want to do this in C?
>> The kind of things you hint at doing elsewhere in your post are trivial
>> in any of the many scripting languages you have available.
>>
>> Anyway, here's one way:
>>
>>      int vnum = 3;
>>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>>
>> Repeat after vnum += 1;.  Whether this is suitable (it's C99) depends in
>> part on why you using C.
>
> I'm having trouble with this, ben:
>
>   int vnum, c, i;
>   FILE *fptr, *gptr;
>
>
>
>   vnum = 3;
>   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);
>
>
>   fptr = fopen (name1, "r");
>   if (fptr == NULL) {
>     printf ("fopen no bueno");
>     exit (1);
>   }
>   vnum += 1;
>
>   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>   int t = snprintf (name2, sizeof name1, name_fmt, base, vnum, ext);
                                         ^--- should be 2 (name2)
That is not a syntax error, nor a language grammar error.
It is just a line cloning error.
It will compile, link, and run without obvious error.
It will some day produce wrong results.

>   gptr = fopen (name2, "w");
>
>   if (gptr == NULL) {
>     printf ("gopen no bueno");
>     exit (1);
>   }
>>
>> <snip>
>> (Your posts will get more helpful replies if they are short and to the
>> point.)
>>
>
> Does the source itself announce what's wrong with it?

Latent bugs are nasty.  Intermittent bugs are worse.  Good luck.

[toc] | [prev] | [next] | [standalone]


#105252

Fromfred flintstone <fred@server.invalid>
Date2017-03-01 06:59 -0800
Message-ID<eho5upFjiksU1@mid.individual.net>
In reply to#105251
On 03/01/2017 06:32 AM, D. Aaron Sawyer wrote:
> On 2017.03.01 09:33, fred flintstone wrote:
>> On 02/27/2017 05:11 AM, Ben Bacarisse wrote:
>>> fred flintstone <fred@server.invalid> writes:
>>> <snip>
>>>> I need to concatenate 'toolchain3.sh' from its constituent parts and
>>>> then increment it as the filename of gptr.
>>>
>>> That's not too hard, but it's much more fiddly in C than in any
>>> scripting language I can think of.  Why do you want to do this in C?
>>> The kind of things you hint at doing elsewhere in your post are trivial
>>> in any of the many scripting languages you have available.
>>>
>>> Anyway, here's one way:
>>>
>>>      int vnum = 3;
>>>      const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>>      char name1[snprintf(0, 0, name_fmt, base, vnum, ext) + 1];
>>>      int s = snprintf(name1, sizeof name1, name_fmt, base, vnum, ext);
>>>
>>> Repeat after vnum += 1;.  Whether this is suitable (it's C99) depends in
>>> part on why you using C.
>>
>> I'm having trouble with this, ben:
>>
>>   int vnum, c, i;
>>   FILE *fptr, *gptr;
>>
>>
>>
>>   vnum = 3;
>>   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>>   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>>   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);
>>
>>
>>   fptr = fopen (name1, "r");
>>   if (fptr == NULL) {
>>     printf ("fopen no bueno");
>>     exit (1);
>>   }
>>   vnum += 1;
>>
>>   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>>   int t = snprintf (name2, sizeof name1, name_fmt, base, vnum, ext);
>                                         ^--- should be 2 (name2)
> That is not a syntax error, nor a language grammar error.
> It is just a line cloning error.
> It will compile, link, and run without obvious error.
> It will some day produce wrong results.

Hmm...still stumped that I'm not getting a file created out of this:

s is 13
name1 is toolchain3.sh
t is 13
name2 is toolchain4.sh
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main (int argc, char *argv[])
{
   int vnum, c, i;
   FILE *fptr, *gptr;



   vnum = 3;
   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);
   printf ("s is %d\n", s);
   printf ("name1 is %s\n", name1);

   fptr = fopen (name1, "r");
   if (fptr == NULL)
     {
       printf ("fopen no bueno");
       exit (1);
     }
   vnum += 1;

   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int t = snprintf (name2, sizeof name2, name_fmt, base, vnum, ext);
   printf ("t is %d\n", t);
   printf ("name2 is %s\n", name2);
   gptr = fopen (name2, "w");

   if (gptr == NULL)
     {
       printf ("gopen no bueno");
       exit (1);
     }

   while (1)
     {
       c = fgetc (fptr);

       if (c == EOF)
	break;
       else
	putc (c, gptr);
     }


   fclose (fptr);
   fclose (gptr);

   return 0;
}
>
>>   gptr = fopen (name2, "w");
>>
>>   if (gptr == NULL) {
>>     printf ("gopen no bueno");
>>     exit (1);
>>   }
>>>
>>> <snip>
>>> (Your posts will get more helpful replies if they are short and to the
>>> point.)
>>>
>>
>> Does the source itself announce what's wrong with it?
>
> Latent bugs are nasty.  Intermittent bugs are worse.  Good luck.

Nice catch. Thanks.
-- 
fred

[toc] | [prev] | [next] | [standalone]


#105253

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-03-01 15:24 +0000
Message-ID<8737exnhph.fsf@bsb.me.uk>
In reply to#105252
fred flintstone <fred@server.invalid> writes:

> On 03/01/2017 06:32 AM, D. Aaron Sawyer wrote:
>> On 2017.03.01 09:33, fred flintstone wrote:
<snip>
>>>   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>>>   int t = snprintf (name2, sizeof name1, name_fmt, base, vnum, ext);
>>                                         ^--- should be 2 (name2)
>> That is not a syntax error, nor a language grammar error.
>> It is just a line cloning error.
>> It will compile, link, and run without obvious error.
>> It will some day produce wrong results.
>
> Hmm...still stumped that I'm not getting a file created out of this:

More information is needed.  The code looks fine and I *do* get the file
created, so I can't investigate why you don't.  If it was a matter of
file permissions you'd get an error opening name2 in "w" mode.

<snip>
>   vnum = 3;
>   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
>   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
>   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);
>   printf ("s is %d\n", s);
>   printf ("name1 is %s\n", name1);
>
>   fptr = fopen (name1, "r");
>   if (fptr == NULL)
>     {
>       printf ("fopen no bueno");
>       exit (1);
>     }

I'd make this a function.  Exactly how much needs to be passed in will
depend on things I don't currently know but here's a guess:

  FILE *open_toolchain_file(int vnum, const char *mode)
  {
      const char *name_fmt = "toolchain%d.sh";
      char fname[snprintf(0, 0, name_fmt, vnum) + 1];
      snprintf(fname, sizeof fname, name_fmt, vnum);

      FILE *fp = fopen(fname, mode);
      if (fp == NULL) {
          fprintf(stderr, "Unable to open %s in %s mode.\n", fname, mode);
          exit(EXIT_FAILURE);
     }
     return fp;
  }

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#105314

Fromfred flintstone <fred@server.invalid>
Date2017-03-02 01:47 -0800
Message-ID<ehq810F1hq0U1@mid.individual.net>
In reply to#105253
On 03/01/2017 07:24 AM, Ben Bacarisse wrote:

> I'd make this a function.  Exactly how much needs to be passed in will
> depend on things I don't currently know but here's a guess:
>
>   FILE *open_toolchain_file(int vnum, const char *mode)
>   {
>       const char *name_fmt = "toolchain%d.sh";
>       char fname[snprintf(0, 0, name_fmt, vnum) + 1];
>       snprintf(fname, sizeof fname, name_fmt, vnum);
>
>       FILE *fp = fopen(fname, mode);
>       if (fp == NULL) {
>           fprintf(stderr, "Unable to open %s in %s mode.\n", fname, mode);
>           exit(EXIT_FAILURE);
>      }
>      return fp;
>   }
>
> <snip>
>

I'll try to implement that. (Really hazy on how to pass in C.)

Switched out main controls:

s is 13
name1 is toolchain3.sh
t is 13
name2 is toolchain4.sh
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main (int argc, char *argv[])
{
   int vnum, c, i;
   FILE *fptr, *gptr;

   vnum = 3;
   const char *base = "toolchain", *ext = "sh", *name_fmt = "%s%d.%s";
   char name1[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int s = snprintf (name1, sizeof name1, name_fmt, base, vnum, ext);
   printf ("s is %d\n", s);
   printf ("name1 is %s\n", name1);

   fptr = fopen (name1, "r");
   if (fptr == NULL)
     {
       printf ("fopen no bueno");
       exit (1);
     }
   vnum += 1;

   char name2[snprintf (0, 0, name_fmt, base, vnum, ext) + 1];
   int t = snprintf (name2, sizeof name2, name_fmt, base, vnum, ext);
   printf ("t is %d\n", t);
   printf ("name2 is %s\n", name2);
   gptr = fopen (name2, "w");

   if (gptr == NULL)
     {
       printf ("gopen no bueno");
       exit (1);
     }


   if (fptr != NULL && gptr != NULL)
     {
       while ((c = getc (fptr)) != EOF)
	{
	  putc (c, gptr);
	}
       fclose (fptr);
       fclose (gptr);
     }
   return 0;
}

Thanks.
-- 
fred

[toc] | [prev] | [next] | [standalone]


#105318

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-03-02 11:05 +0000
Message-ID<87a894lz0t.fsf@bsb.me.uk>
In reply to#105314
fred flintstone <fred@server.invalid> writes:

> On 03/01/2017 07:24 AM, Ben Bacarisse wrote:
>
>> I'd make this a function.  Exactly how much needs to be passed in will
>> depend on things I don't currently know but here's a guess:
>>
>>   FILE *open_toolchain_file(int vnum, const char *mode)
>>   {
>>       const char *name_fmt = "toolchain%d.sh";
>>       char fname[snprintf(0, 0, name_fmt, vnum) + 1];
>>       snprintf(fname, sizeof fname, name_fmt, vnum);
>>
>>       FILE *fp = fopen(fname, mode);
>>       if (fp == NULL) {
>>           fprintf(stderr, "Unable to open %s in %s mode.\n", fname, mode);
>>           exit(EXIT_FAILURE);
>>      }
>>      return fp;
>>   }
>>
>> <snip>
>>
>
> I'll try to implement that. (Really hazy on how to pass in C.)

Ah, no, don't.  When someone shows a fragment of code (or an exploratory
program) all sorts of possible ways of tidying it up present themselves,
but now that I've a complete program that's closer (or maybe is) what
you are finally aiming for, I don't think the function above will help
at all.  (Something a bit like it might, but certainly not as written.)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#104851

Fromjt@toerring.de (Jens Thoms Toerring)
Date2017-02-27 13:33 +0000
Message-ID<ehio5pFglhsU1@mid.uni-berlin.de>
In reply to#104841
fred flintstone <fred@server.invalid> wrote:
From: jt@toerring.de (Jens Thoms Toerring)
To: fred flintstone <fred@server.invalid>
Subject: Re: writing a c program to substitute text
In-Reply-To: <ehiij4Ffgn1U1@mid.individual.net>
X-Newsgroups: comp.lang.c

In article <ehiij4Ffgn1U1@mid.individual.net> you wrote:
> It seems I need code to describe the type of code I want. I honestly 
> thought I had to come up with a number that wouldn't be smaller in bytes 
> than whatever I'm storing in a string.

> Let me cough up some source and address a specification:

> #include <stdio.h>
> #include <stdlib.h>

> int main(void)
> {
>     int version;
>     int c;
>     FILE *fptr, *gptr;
>     const char *executable1 = "arrow";
>     const char *executable2 = "mahershala";
>     const char *base = "toolchain";
>     const char *ext = "sh";
>     fptr = fopen("toolchain3.sh","r");

>     if(fptr == NULL)
>     {
>        printf("fopen no bueno");
>        exit(1);
>     }

<snipped>

> I need to concatenate 'toolchain3.sh' from its constituent parts and 
> then increment it as the filename of gptr.

If you need to concatenate twp strings, the result tring needs
to be large enough to accomodate both, obviously. And in order
write to a string it can't be a const char pointer, you'll need
an modifiable array.

There's no string type in C. All you have is char arrays.
And a char array that contains a '\0' character can be called
a string - "strings" are just char arrays containing a "sen-
tinel" element that indicates where the content ends. All
the built-in "string"-handling function expect such a char
array containing a '\0' somewhere as inputs (and try to
return such kind of arrays).

A const char * like this is a special case:

const char * txt = "bar";

Is a pointer to an array of chars that resides (often in
write-only) memory and that is ininitialized ith the four
chars 'b', 'a', 'r' and '\0'. Note that when you have

const char * txt1 = "bar";
const char * txt2 = "foobar";

'txt1' could end up being a pointer to the 4th character
in 'txt2'!

You can change what such a pointer points to, but not the
content of what it points to (i.e. the string itself. For
that you need an array:

char txt[4] = "bar";

This is a char array with 4 elements that is initialized
to the same sequence of chars as above (the '4' is optional
when you initialize it like this). You can change any of
the chars it contains (but make sure that at least one of
them is a '\0' - or it won't be string anymore but a mere
array of chars).

Obviously, this won't do if you want to append another string
to it since there's no room left for that. If you know in
advance how long the resulting string is going ti be you
could define it with a larger size, e.g.

char txt[8] = "bar";
strcat(txt, ".exe");

This is correct since the resulting string "bar.exe" requires
8 chars (including the trailing '\0'). Of course, you can
make it larger if you feel like it.

If you have no idea jow long the strings will become you'll
have to use a different strategy, you need to use allocated
memory. Take a simple function that concatenates two strings
of lengths unknown at compile time.

char * mycat(const char * a, const char *b)
{
    char *res = malloc(strlen(a) + strlen(b) + 1);
    if (res != NULL) {
         strcpy(p, res);
         strcal(p, res);
    }
    return ret;
}

Note first that this function takes two arguments that are
of type const char *. This does not imply that both the
arguments have to be const char pointers, it could also be
pointers to modifiable arrays (or arrays of allocated memory
as returned by this function). Note second that it's the
responsibility of the caller to make sure that both are
strings, i.e. pointers to char arrays that contain a '\0'.
Note third that function will return a NULL pointer if
there was not enough memory available. And, finally, the
caller bears the responsibility of free()-ing the returned
string once he's done with it.

These are the building blocks you get in C (plus a few func-
tions for strung handling). All the rest you've got for
yourself. It's a lot more time-consuming to write correct
code for that than in other languages - but which often them-
selves are implemented in C and just hide the complexity from
you (and typically are a lot slower since they must implement
the most general case).

E.g., if you do in Perl

my $n = 18;
my $str = "bar$n";

then I C you could have function for this likr

char * append_int(const char *pre, int n)
{
    char * res = malloc(strlen(pre) + (n ? (log(labs(n)) + 2) : 1) + 1);
    if (res)
        sprintf(res, "%s%d", pre, n);
    return res;
}

The 'log(labs(n)) + 2' is there to determine how many digits
the value of n will require when represented as a string
(and keeping in mind that it might be negative). The case
of n == 0 must be treated specially since log(0) is not
defined. If the function returns NULL this, again, indi-
cates that not enough memory was available.

You could use these functions to assemble your filename,
e.g. like this

    const char * basename = "toolchain";
    const char * ext = ".sh";
    char * p;
    char * name = NULL;
    FILE *fptr;
    
    if ((p = append_int(basename, 3)) != NULL) {
        name = mycat(p, ext);
        free(p);
    }

    if (name == NULL)
        fprintf(stderr, "Out of memory\n");
        exit( EXIT_FAILURE;
    }
    
    fptr = fopen(name, "r");
    
    if (fptr == NULL) {
        fprintf(stderr, "Failed to open %s for reading\n", name);
        free(name);
        exit(EXIT_FAILURE);
    }
    
    free(name);

Of course, you can avoid the complexities of using allocated
memory (and the ensuing rquirement to release it when not
needed anymore to avoid memory leaks) if you have a reliable
upper limit of the lengths of your strings. Though this can
often be difficult to predict and a wrong guess can lead to
catastrophic failure of you're program.

                             Regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


#104892

FromKeith Thompson <kst-u@mib.org>
Date2017-02-27 09:10 -0800
Message-ID<lnshmzftl3.fsf@kst-u.example.com>
In reply to#104851
jt@toerring.de (Jens Thoms Toerring) writes:
[...]
> A const char * like this is a special case:
>
> const char * txt = "bar";
>
> Is a pointer to an array of chars that resides (often in
> write-only) memory and that is ininitialized ith the four
> chars 'b', 'a', 'r' and '\0'.

I'm pretty sure you meant "read-only", not "write-only".

[...]

> char * mycat(const char * a, const char *b)
[...]
>
> Note first that this function takes two arguments that are
> of type const char *. This does not imply that both the
> arguments have to be const char pointers, it could also be
> pointers to modifiable arrays (or arrays of allocated memory
> as returned by this function). Note second that it's the
> responsibility of the caller to make sure that both are
> strings, i.e. pointers to char arrays that contain a '\0'.

Correction: it's the responsibility of the caller to make sure
that both are *pointers to* strings.  (A "pointer to a string"
is by definition a pointer to the initial character of a string.)

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


Page 1 of 5  [1] 2 3 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web