By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,238 Members | 1,837 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

a dumb strcat question

P: n/a
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123
main()
{
char *sfun(char *);
printf("%s",sfun("123"));
}

char *sfun(char *s)
{
static char *quote = "\"";
char *outs;
outs = quote;
strcat(outs,s); // outs = "123
strcat(outs,quote); // outs = nada why?
return (outs);
}
Nov 13 '05 #1
Share this Question
Share on Google+
23 Replies


P: n/a
David Frank <da********@hotmail.com> scribbled the following:
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123
main()
{
char *sfun(char *);
printf("%s",sfun("123"));
} char *sfun(char *s)
{
static char *quote = "\"";
char *outs;
outs = quote;
strcat(outs,s); // outs = "123
No. This causes undefined behaviour by modifying a literal string.
strcat(outs,quote); // outs = nada why?
Well, if we assume that the above strcat call succeeded (and did
what you thought it did), then outs==quote will still be true,
so this call is effectively strcat(outs, outs). strcatting a string
onto itself is quite an interesting thing to try...
return (outs);
}


Perhaps you could try this?

char *sfun(char *s)
{
char *outs = malloc(strlen(s)+3);
if (outs) {
sprintf(outs, "\"%s\"", s);
}
return outs;
}

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Shh! The maestro is decomposing!"
- Gary Larson
Nov 13 '05 #2

P: n/a
in comp.lang.c i read:
How can I write a string function that encloses the input string
in quotes "string" ??


how? you could learn c. since this isn't likely, and for reasons even i
cannot understand, i will therefore provide you with such a function:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
`quote' the input string. existing quoting is not escaped.
returns fresh storage, caller is responsible for disposal.
*/
char *sfun(const char *const s)
{
char *new = malloc(strlen(s) + 3);
if (0 != new) sprintf(new, "\"%s\"", s);
return new;
}

example usage:

#include <stdio.h>
#include <stdlib.h>
char *sfun(const char * const s);
int main(void)
{
char *p = "some string", *q = sfun(p);
fputs("original : ", stdout); puts(p);
fputs("processed: ", stdout); puts(q);
free(q);
return 0;
}

--
a signature
Nov 13 '05 #3

P: n/a

"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
David Frank <da********@hotmail.com> scribbled the following:
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123
main()
{
char *sfun(char *);
printf("%s",sfun("123"));
}

char *sfun(char *s)
{
static char *quote = "\"";
char *outs;
outs = quote;
strcat(outs,s); // outs = "123


No. This causes undefined behaviour by modifying a literal string.
strcat(outs,quote); // outs = nada why?


Well, if we assume that the above strcat call succeeded (and did
what you thought it did), then outs==quote will still be true,
so this call is effectively strcat(outs, outs). strcatting a string
onto itself is quite an interesting thing to try...
return (outs);
}


Perhaps you could try this?

char *sfun(char *s)
{
char *outs = malloc(strlen(s)+3);
if (outs) {
sprintf(outs, "\"%s\"", s);
}
return outs;
}

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) -------------

Finland --------\ \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/ "Shh! The maestro is decomposing!"
- Gary Larson


The malloc statement above gets a warning (below), but the routine
outputs "123" as requested, the following warning is a constant
bane in ALL my attempts at C programming and is a chief reason
I remain a Fortran programmer.
(kinda makes me <smile> to see it bite experienced C programmers)
THANKS!!
test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels
of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj
Nov 13 '05 #4

P: n/a

"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
strcatting a string
onto itself is quite an interesting thing to try...


Since its a function, not a subroutine, I dont understand thats
whats happening..

Perhaps the fortran function below I am trying to translate to C
will explain further, (note no MALLOC is required)..

program varying_string_output
write (*,*) enclose('123'),',' ! outputs "123",
write (*,*) enclose('the lazy dog'),',' ! outputs "the lazy dog",
stop

contains
function enclose(s1) result(s2)
character(*) :: s1
character(len_trim(s1)+2) :: s2 ! output length = input length+2
s2 = '"' // trim(s1) // '"' ! enclose "string" in quotes
end function
end program

Nov 13 '05 #5

P: n/a
nrk
David Frank wrote:

"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
David Frank <da********@hotmail.com> scribbled the following:
> How can I write a string function that encloses the input string
> in quotes "string" ??
> below works for the "123 operation but adding " to it
> clobbers the "123


> main()
> {
> char *sfun(char *);
> printf("%s",sfun("123"));
> }

> char *sfun(char *s)
> {
> static char *quote = "\"";
> char *outs;
> outs = quote;
> strcat(outs,s); // outs = "123


No. This causes undefined behaviour by modifying a literal string.
> strcat(outs,quote); // outs = nada why?


Well, if we assume that the above strcat call succeeded (and did
what you thought it did), then outs==quote will still be true,
so this call is effectively strcat(outs, outs). strcatting a string
onto itself is quite an interesting thing to try...
> return (outs);
> }


Perhaps you could try this?

char *sfun(char *s)
{
char *outs = malloc(strlen(s)+3);
if (outs) {
sprintf(outs, "\"%s\"", s);
}
return outs;
}

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) -------------

Finland --------\
\-- http://www.helsinki.fi/~palaste ---------------------

rules! --------/
"Shh! The maestro is decomposing!"
- Gary Larson


The malloc statement above gets a warning (below), but the routine
outputs "123" as requested, the following warning is a constant
bane in ALL my attempts at C programming and is a chief reason
I remain a Fortran programmer.
(kinda makes me <smile> to see it bite experienced C programmers)
THANKS!!
test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels
of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj

Probably the most obscure warning for a missing function prototype you can
get. What the compiler is trying to tell u[*] here is that you've
forgotten to add "#include <stdlib.h>" (which has the prototype for malloc)
in your code. I know for certain that Joona knows he has to include
stdlib.h to use malloc. Sometimes however, we don't make enough allowance
for a newbie's lack of knowledge :-)

-nrk.
[*] - My nod to Joona's masterful troll. There Joona, another Indian
satisfying your stereotype :-)
Nov 13 '05 #6

P: n/a
David Frank <da********@hotmail.com> scribbled the following:
"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
strcatting a string
onto itself is quite an interesting thing to try...
Since its a function, not a subroutine, I dont understand thats
whats happening.. Perhaps the fortran function below I am trying to translate to C
will explain further, (note no MALLOC is required)..
Sorry, my experience in Fortran is exactly zilch. Some really high
programming guru, please explain the difference to both of us.
program varying_string_output
write (*,*) enclose('123'),',' ! outputs "123",
write (*,*) enclose('the lazy dog'),',' ! outputs "the lazy dog",
stop contains
function enclose(s1) result(s2)
character(*) :: s1
character(len_trim(s1)+2) :: s2 ! output length = input length+2
s2 = '"' // trim(s1) // '"' ! enclose "string" in quotes
end function
end program


--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Make money fast! Don't feed it!"
- Anon
Nov 13 '05 #7

P: n/a
David Frank wrote:

How can I write a string function that encloses the input string
in quotes "string" ??


Is there a problem with: printf("\"%s\"", thestring);

(or similar with sprintf to an internal string).

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #8

P: n/a
In article <SA********************@twister.tampabay.rr.com> ,
"David Frank" <da********@hotmail.com> wrote:
The malloc statement above gets a warning (below), but the routine
outputs "123" as requested, the following warning is a constant
bane in ALL my attempts at C programming and is a chief reason
I remain a Fortran programmer.
That is probably a good idea until you've figured out why you get a
warning. (Actually, you only get a warning because the compiler you are
using compiles some completely illegal C code while only producing a
warning).
(kinda makes me <smile> to see it bite experienced C programmers)
THANKS!!
test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels
of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj

Nov 13 '05 #9

P: n/a
bd
David Frank wrote:

"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
David Frank <da********@hotmail.com> scribbled the following:
> How can I write a string function that encloses the input string
> in quotes "string" ??
> below works for the "123 operation but adding " to it
> clobbers the "123


> main()
> {
> char *sfun(char *);
> printf("%s",sfun("123"));
> }

> char *sfun(char *s)
> {
> static char *quote = "\"";
> char *outs;
> outs = quote;
> strcat(outs,s); // outs = "123


No. This causes undefined behaviour by modifying a literal string.
> strcat(outs,quote); // outs = nada why?


Well, if we assume that the above strcat call succeeded (and did
what you thought it did), then outs==quote will still be true,
so this call is effectively strcat(outs, outs). strcatting a string
onto itself is quite an interesting thing to try...
> return (outs);
> }


Perhaps you could try this?

char *sfun(char *s)
{
char *outs = malloc(strlen(s)+3);
if (outs) {
sprintf(outs, "\"%s\"", s);
}
return outs;
}

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) -------------

Finland --------\
\-- http://www.helsinki.fi/~palaste ---------------------

rules! --------/
"Shh! The maestro is decomposing!"
- Gary Larson


The malloc statement above gets a warning (below), but the routine
outputs "123" as requested, the following warning is a constant
bane in ALL my attempts at C programming and is a chief reason
I remain a Fortran programmer.
(kinda makes me <smile> to see it bite experienced C programmers)
THANKS!!
test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels
of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj


Are you compiling in C++ mode? That might cause such a warning. Which line
was line 8 in your test program?
Nov 13 '05 #10

P: n/a
bd wrote:
David Frank wrote:

test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels
of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj

Are you compiling in C++ mode? That might cause such a warning. Which line
was line 8 in your test program?


No, it almost certainly would not give a warning. It would give an error
and halt compilation. That is, all implementations I've heard of would
almost certainly do that. The C++ standard only required a "diagnostic",
of course. But I've never heard of a compiler accepting a constraint
violation with only a warning.

The problem is obviously that malloc is not declared. In C++ and C99,
that would make calling it an error. In C prior to C99, it implicitly
declares the function with return type int.

Arguably, the main issue here is the quality of the compiler. Warning
about an implicit function declaration is pretty standard fare for most
good compilers.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #11

P: n/a

"bd" <bd*****@users.sf.net> wrote in message
news:gj************@bd-home-comp.no-ip.org...
David Frank wrote:
<snip>

The malloc statement above gets a warning (below), but the routine
outputs "123" as requested, the following warning is a constant
bane in ALL my attempts at C programming and is a chief reason
I remain a Fortran programmer.
(kinda makes me <smile> to see it bite experienced C programmers)
THANKS!!
test.c(8) : warning C4047: 'initializing' : 'char *' differs in levels of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj

Were you compiling in C++ mode? That might cause such a warning.

Which line was line 8 in your test program?

statement 8 is like i said, the malloc statement
I dont even know how to invoke C++ mode,
I used the following compile command, and dont even know
a alternative (I very seldom invoke my limited C knowledge)..

CL test.c


Nov 13 '05 #12

P: n/a
"Kevin Goodsell" <us*********************@neverbox.com> wrote:
But I've never heard of a compiler accepting a constraint
violation with only a warning.


Really?

int main(void)
{
char *p = 0;
unsigned char *q = p; /* CONSTRAINT VIOLATION */
return 0;
}

C:\docs\prog\c>gcc -ansi -pedantic suchar.c
suchar.c: In function `main':
suchar.c:4: warning: pointer targets in initialization differ in signedness

BCC 5.5 appears to require the argument -wucp to specifically
enable this 'warning'. It is not mentioned in the documentation
that it is necessary to specify that argument to implement a
conforming ANSI C compiler.

LCC 3.8, with both the -A (activate all warnings) and -ansic
(disallow the language extensions of lcc-win32) appears not
to generate any diagnostic at all (making it non-conforming).

--
Simon.
Nov 13 '05 #13

P: n/a
David Frank wrote:
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123


There are three different ways to write C functions that return
strings, none of them 100% perfect.

1) Return a pointer to a static string
2) Use a user supplied character array
3) Return a pointer supplied by malloc()

Once you decide which of those you want to use, it is easy to write.

-- glen

Nov 14 '05 #14

P: n/a

"glen herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote in message
news:xkcBb.343897$ao4.1153084@attbi_s51...
David Frank wrote:
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123


There are three different ways to write C functions that return
strings, none of them 100% perfect.

1) Return a pointer to a static string
2) Use a user supplied character array
3) Return a pointer supplied by malloc()

Once you decide which of those you want to use, it is easy to write.

-- glen


Perhaps the fortran function below I am trying to translate to C
will explain further, (note no MALLOC is required)..

program varying_string_output
write (*,*) enclose('123'),',' ! outputs "123",
write (*,*) enclose('the lazy dog'),',' ! outputs "the lazy dog",
stop

contains
function enclose(s1) result(s2)
character(*) :: s1
character(len_trim(s1)+2) :: s2 ! output length = input length+2
s2 = '"' // trim(s1) // '"' ! enclose "string" in quotes
end function
end program

Nov 14 '05 #15

P: n/a

On Tue, 9 Dec 2003, David Frank wrote:

"glen herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote...
David Frank wrote:
How can I write a string function that encloses the input string
in quotes "string" ??
below works for the "123 operation but adding " to it
clobbers the "123
1) Return a pointer to a static string
2) Use a user supplied character array
3) Return a pointer supplied by malloc()
Perhaps the fortran function below I am trying to translate to C
will explain further, (note no MALLOC is required)..
Well, apparently the Fortran function below *doesn't* help; not
enough, anyway, because you've posted it twice now and I don't
think anyone's really solved your problem. So maybe you should
try to explain your question in one of the languages more commonly
used on this newsgroup, such as C or English. (Heck, German would
probably get the job done, too, but it wouldn't be as welcomed as
English. ;-)
I'm going to try to decode your program anyway, and you can tell
me if I get it right.
program varying_string_output
write (*,*) enclose('123'),',' ! outputs "123",
Since writing a C program to output "123" is trivial, I assume
you're wanting to write a C function that takes a string such as
'123' and encloses it in quotes: '"123"', like that.
write (*,*) enclose('the lazy dog'),',' ! outputs "the lazy dog",
stop

contains
function enclose(s1) result(s2)
character(*) :: s1
character(len_trim(s1)+2) :: s2 ! output length = input length+2
s2 = '"' // trim(s1) // '"' ! enclose "string" in quotes
I don't know what 'trim(s1)' does, but I'll assume that 'trim' is
a no-op in this context.
end function
end program

So three ways of doing this are
1) Return a pointer to a static string
/* Fails if the user passes a 'src' longer than MAX_STRING_LENGTH;
* each call overwrites the old string */
const char *enclose(const char *src)
{
static char buffer[MAX_STRING_LENGTH];
if (strlen(src)+3 > sizeof buffer)
return NULL;
sprintf(buffer, "\"%s\"", src);
return buffer;
}
2) Use a user supplied character array
/* Undefined behavior if the user passes an invalid 'dst' */
char *enclose(const char *src, char *dst)
{
sprintf(dst, "\"%s\"", src);
return dst;
}
3) Return a pointer supplied by malloc()


/* Fails if malloc fails; user must free() the supplied string */
char *enclose(const char *src)
{
char *p = malloc(strlen(src)+3);
if (p != NULL)
sprintf(p, "\"%s\"", src);
return p;
}
Note that in *none* of these cases can you write

printf("%s %s\n", enclose("abc"), enclose("def"));

and have it work correctly. In Case 1, you get unspecified
behavior because both calls to 'enclose' are trying to write
on the same chunk of memory. In Case 2, you just flat out are
supplying the wrong number of arguments. And in Case 3, it works
just fine -- but you have a memory leak because you never 'free()'
the allocated strings. The correct use of each function might be

/* Case 1 */
printf("%s ", enclose("abc")); /* get a semicolon between them */
printf("%s\n", enclose("def"));

/* Case 2 */
char p[4], q[4];
printf("%s %s\n", enclose("abc", p), enclose("def", q));

/* Case 3 */
char *p = enclose("abc");
char *q = enclose("def");
printf("%s %s\n", p, q);
free(p);
free(q);

Which of these methods you use depends on your personal style
and the convenience of each of them for your particular project.

HTH,
-Arthur
Nov 14 '05 #16

P: n/a
In article <news:Pi**********************************@unix45. andrew.cmu.edu>
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> writes:
["enclose" function snipped, but note that it adds 2 more bytes to
an existing string]
/* Case 2 */
char p[4], q[4];
printf("%s %s\n", enclose("abc", p), enclose("def", q));


Actually, p and q both need to be at least 6 elements long,
because "\"abc\"" and "\"def\"" both have a strlen() of 5,
and as always, it takes N+1 characters to store a string
whose strlen() is N.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #17

P: n/a
"Arthur J. O'Dwyer" wrote:
On Tue, 9 Dec 2003, David Frank wrote:
"glen herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote...
David Frank wrote:

> How can I write a string function that encloses the input string
> in quotes "string" ??
> below works for the "123 operation but adding " to it
> clobbers the "123 1) Return a pointer to a static string
2) Use a user supplied character array
3) Return a pointer supplied by malloc()

.... snip ...
Note that in *none* of these cases can you write

printf("%s %s\n", enclose("abc"), enclose("def"));

and have it work correctly. In Case 1, you get unspecified
behavior because both calls to 'enclose' are trying to write
on the same chunk of memory. In Case 2, you just flat out are


Wanna bet? I can make that printf work for static allocations,
with some limitations. The secret is a limited set of internal
buffers, used in sequence, with automatic initialization.

/* The limitations */
#define BUFMAX 128
#define BUFCNT 4

#include <stdlib.h>

struct buf {
struct buf *next;
char *ch;
};

char *enclose(const char *s)
{
static struct buf *cp;
struct buf *p;
int i;

if (NULL == cp) {
for (i = 0; i < BUFCNT; i++) {
if (p = malloc(sizeof *p)) {
p->next = cp;
if (p->ch = malloc(BUFMAX)) cp = p;
else {
free(p);
break;
}
}
}
p = cp;
while (p->next) p = p->next;
p->next = cp;
}
cp = cp->next;
/* Use cp->ch to form the 'enclosed' string */
return cp->ch;
} /* untested */

We can avoid malloc, with less flexibility, using static arrays of
char buffers and next pointers and a static index.

This method of using a limited set of internal buffers has many
applications. It concentrates the time consuming and failure
prone operations of forming the buffers at initialization time, so
it is quite suitable for embedded machines. Just call the routine
at least once during startup.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #18

P: n/a
nrk <ra*********@deadbeef.verizon.net> wrote:
David Frank wrote:
"Joona I Palaste" <pa*****@cc.helsinki.fi> wrote in message
news:bq**********@oravannahka.helsinki.fi...
David Frank <da********@hotmail.com> scribbled the following:
[...] test.c(8) : warning C4047: 'initializing' : 'char *' differs in
levels of indirection from 'int '
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:test.exe
test.obj

Probably the most obscure warning for a missing function prototype
you can get. What the compiler is trying to tell u[*] here is that
you've forgotten to add "#include <stdlib.h>" (which has the
prototype for malloc) in your code. I know for certain that Joona
knows he has to include stdlib.h to use malloc. Sometimes however,
we don't make enough allowance for a newbie's lack of knowledge :-)

David. Like with most compilers, when you use MSVC's cl.exe you should
always supply some command-line options to have it behave 'better'.
Otherwise use the IDE, it should default such options. I always run with
warning level 3 or sometimes 4, and you should also disable language
extensions. You can default these by doing "set CL=/W3 /Za" before running
the compiler. This will normally make it easier to understand what's going
on.

Compiling the above code thus gives much more useful output: noting the lack
of declarations for the three library functions.

C:\>cl /W4 /Za clc6.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

clc6.c
clc6.c(4) : warning C4013: 'malloc' undefined; assuming extern returning int
clc6.c(4) : warning C4013: 'strlen' undefined; assuming extern returning int
clc6.c(4) : warning C4047: 'initializing' : 'char *' differs in levels of
indirection from 'int '
clc6.c(6) : warning C4013: 'sprintf' undefined; assuming extern returning
int
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:clc6.exe
clc6.obj
LIBC.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
clc6.exe : fatal error LNK1120: 1 unresolved externals

--
Alan J. McFarlane
http://homepage.ntlworld.com/alanjmcf/
Please follow-up in the newsgroup for the benefit of all.
Nov 14 '05 #19

P: n/a

On Tue, 9 Dec 2003, Chris Torek wrote:
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> writes:
["enclose" function snipped, but note that it adds 2 more bytes to
an existing string]
/* Case 2 */
char p[4], q[4];
printf("%s %s\n", enclose("abc", p), enclose("def", q));


Actually, p and q both need to be at least 6 elements long,
because "\"abc\"" and "\"def\"" both have a strlen() of 5,
and as always, it takes N+1 characters to store a string
whose strlen() is N.


Yes, of course you're right. I forgot what 'enclose' was
doing, there. :-(

-Arthur

Nov 14 '05 #20

P: n/a
On Tue, 9 Dec 2003 01:12:54 -0500 (EST), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:
On Tue, 9 Dec 2003, David Frank wrote: <snip>
> How can I write a string function that encloses the input string
> in quotes "string" ??
<snip> Perhaps the fortran function below I am trying to translate to C
will explain further, (note no MALLOC is required).. <snip> Since writing a C program to output "123" is trivial, I assume
you're wanting to write a C function that takes a string such as
'123' and encloses it in quotes: '"123"', like that.

Right. Or at least that's what he asked for. Based on past behavior in
comp.lang.fortran and .pl1 it is unlikely David Frank *wants* to do
anything useful or even correct.
write (*,*) enclose('the lazy dog'),',' ! outputs "the lazy dog",
stop

contains
function enclose(s1) result(s2)
character(*) :: s1
character(len_trim(s1)+2) :: s2 ! output length = input length+2
s2 = '"' // trim(s1) // '"' ! enclose "string" in quotes


I don't know what 'trim(s1)' does, but I'll assume that 'trim' is
a no-op in this context.

In "basic" Fortran (ISO/IEC 1539-1:1997 aka F95) character strings are
fixed length, (right) padded with blanks. It is often necessary to
remove those blanks, and the instrinsic (builtin) function TRIM does
that, while LEN_TRIM returns the number of characters in a string
excluding trailing blanks i.e. the "valid" length. (An optional "part"
1539-2 adds dynamically varying strings, like C++ std::string or Ada
Unbounded_String or any number of heapptr+count(s) C packages.)

In his example *usage* the (actual) argument is a string literal,
hence (exact length) unpadded, so TRIM was a no-op. More generally it
would have been used on a variable and the TRIM would matter.
end function
end program

So three ways of doing this are <snip usual suspects>


It is true that Fortran has an advantage in this area, in that it can
return as a value an array or a character string -- and in Fortran
like PL/1 and COBOL but unlike C, Pascal and Ada character string is a
distinct type not just array of character -- including with certain
limitations dynamically-determined sizes/lengths of same, without the
programmer having to manage storage allocation. C "don't do dat". You
can work around it more or less well, or bypass it by using your own
string package, but it remains a (tolerable) deficiency.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #21

P: n/a

"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:65********************************@4ax.com...

<snip> long-nested reply

It is true that Fortran has an advantage in this area, in that it > can return as a value an array or a character string


FYI my topic in comp.lang.fortran was
"string function called by C challenge"

After reading Arthur O'Connells reply here, I made a decision
that my C exec interface shown needed a new interface.
Below is how a Fortran function could interface to a DEFAULT
C code calling what it thinks is a C function that returns a
string via adding a argument.

My last message in comp.lang.fortran was posted yesterday in
"string function called by C challenge" topic (see below)
--------------------------------------
Revised TEST.C program with revised interface for enclose
function(s)

afaik, the fortran attribute [C] used is only supported
by MS, CVF, and probably Intel Visual Fortran.

I dont know if F2003 supports with the usual
substitution for Microsoft syntax, anyone know?

main() // TEST.C
{
int c_enclose(char *, char *); // interface C function
int enclose(char *, char *); // interface Fortran function
char c_outs[999];
char outs[999];
int n;

n = c_enclose("the quick brown fox jumped over ",c_outs);
printf("%s%s\n", c_outs,",");

n = enclose("the lazy dog's back. ",outs);
printf("%s%s\n", outs,",");
}

int c_enclose(char *src, char *dst)
{
sprintf(dst, "\'%s\'", src);
return 0;
}

! ------------------------------------
integer function enclose [C] (is1,is2)
integer :: is1, is2 ; pointer (is1,s1), (is2,s2)
character(999) :: s1, s2
integer :: clen

clen = len_trim(s1(1:index(s1,char(0))-1 )) ! trimmed s1 length
s2(1:clen+3) = "'" // s1(1:lens1) // "'" // char(0)
enclose = 0
end function

Nov 14 '05 #22

P: n/a

"David Frank" <da********@hotmail.com> wrote in message
news:Lj*********************@twister.tampabay.rr.c om...
After reading Arthur O'Connells reply here, I made a decision
that my C exec interface shown needed a new interface.


Correction: it was Arthur J. O'Dwyer's reply what I found
most helpful, thanks Arthur..

Nov 14 '05 #23

P: n/a
David Frank wrote:

"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:65********************************@4ax.com...


To c.l.c:

if you want to see what comes from answering David-Frank-challenges,
feel free to visit c.l.pl1,
otherwise, just don't, please!

(nearly a Trollalert)

Wolfgang
Nov 14 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.