Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #104752 > unrolled thread
| Started by | fred flintstone <fred@server.invalid> |
|---|---|
| First post | 2017-02-26 04:14 -0800 |
| Last post | 2017-02-28 08:46 -0800 |
| Articles | 20 on this page of 86 — 21 participants |
Back to article view | Back to comp.lang.c
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 →
| From | fred flintstone <fred@server.invalid> |
|---|---|
| Date | 2017-02-26 04:14 -0800 |
| Subject | writing 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]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2017-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-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]
| From | fred flintstone <fred@server.invalid> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | Manfred <noname@invalid.add> |
|---|---|
| Date | 2017-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]
| From | fred flintstone <fred@server.invalid> |
|---|---|
| Date | 2017-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]
| From | "D. Aaron Sawyer" <aaron@110.net> |
|---|---|
| Date | 2017-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]
| From | fred flintstone <fred@server.invalid> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | fred flintstone <fred@server.invalid> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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