I need help

J

janus

Hello All,

I found this is a code I am currently studying, could someone explain it to me.

char * string = "Simulated Annealing = 12847369";
char * value = strchr(string, '=');

*(value ++ ) = 0;


printf("%s ==== %s", value, string);

I noticed that sting will print in a new line, why this?

char* karmarkar = "Karmarkar 958572";
I want to use strchr to find the first occurrence of "space" in string karmarkar.
How do I do that?

Regards,
Janus
 
H

Heinrich Wolf

janus said:
Hello All,

I found this is a code I am currently studying, could someone explain it
to me.

char * string = "Simulated Annealing = 12847369";
char * value = strchr(string, '=');

strchr returns a char* pointing to the '=' within string:
*(value ++ ) = 0;

I'm not quite sure about the preceedence of operations. But I think,
first '=' is replaced by '\0', thus truncating string. value would then be
"",
but is advanced with ++ by on character in string, so pointing now to "
12847369"
printf("%s ==== %s", value, string);

Using the explanation above I expect it to print
"Simulated Annealing ==== 12847369"
I noticed that sting will print in a new line, why this?

I do not understand.
char* karmarkar = "Karmarkar 958572";
I want to use strchr to find the first occurrence of "space" in string
karmarkar.
How do I do that?

strchr(karmarkar, ' ')
Regards,
Janus

kind regards
Heiner
 
J

Joachim Schmitz

janus said:
Hello All,

I found this is a code I am currently studying, could someone explain
it to me.

char * string = "Simulated Annealing = 12847369";
char * value = strchr(string, '=');

*(value ++ ) = 0;

This should really result in a segfault, you're writing into a read only
('const') string.
printf("%s ==== %s", value, string);

I noticed that sting will print in a new line, why this?

Guess this is undefined behavoir and bad luck. I had better luck: the
program aborted.
Make the first line look like this and it should work properly:

char string[] = "Simulated Annealing = 12847369";
char* karmarkar = "Karmarkar 958572";
I want to use strchr to find the first occurrence of "space" in
string karmarkar. How do I do that?

char * value = strchr(karmarkar, " ");

Bye, Jojo
 
J

Joachim Schmitz

Joachim said:
janus said:
Hello All,

I found this is a code I am currently studying, could someone explain
it to me.

char * string = "Simulated Annealing = 12847369";
char * value = strchr(string, '=');

*(value ++ ) = 0;

This should really result in a segfault, you're writing into a read
only ('const') string.
printf("%s ==== %s", value, string);

I noticed that sting will print in a new line, why this?

Guess this is undefined behavoir and bad luck. I had better luck: the
program aborted.
Make the first line look like this and it should work properly:

char string[] = "Simulated Annealing = 12847369";
char* karmarkar = "Karmarkar 958572";
I want to use strchr to find the first occurrence of "space" in
string karmarkar. How do I do that?

char * value = strchr(karmarkar, " ");

Sorry, I meant
char * value = strchr(karmarkar, ' ');

Bye, Jojo
 
J

Joachim Schmitz

Heinrich said:
strchr returns a char* pointing to the '=' within string:


I'm not quite sure about the preceedence of operations. But I think,
first '=' is replaced by '\0', thus truncating string. value would
then be "",
but is advanced with ++ by on character in string, so pointing now to
" 12847369"

That's how I read it too
Using the explanation above I expect it to print
"Simulated Annealing ==== 12847369"

It does print " 12847369 ==== Simulated Annealing ",
after having fixed the 1st line...

Bye, Jojo
 
H

Heinrich Wolf

....
This should really result in a segfault, you're writing into a read only
('const') string.

You are right! I missed that.

....
char * value = strchr(karmarkar, " ");

char * value = strstr(karmarkar, " ");
or
char * value = strchr(karmarkar, ' ');
 
J

James Kuyper

janus wrote: ....

This should really result in a segfault, you're writing into a read only
('const') string.

It's not 'const'. Attempting to write to it does have explicitly
undefined behavior, (6.4.5p6). However, that's completely separate from
the fact that attempting to write to an object defined with 'const' is
undefined behavior (6.7.3p5).

The fact that the behavior is undefined doesn't mean that it "should
segfault". If the standard did say that it "should segfault", that would
correspond to defining the behavior. In point of fact, one of the single
most common ways programs behave, when their behavior is undefined, is
in precisely the way their author inappropriately expects them to behave.
 
E

Eric Sosman

Hello All,

I found this is a code I am currently studying, could someone explain it to me.

char * string = "Simulated Annealing = 12847369";
char * value = strchr(string, '=');

*(value ++ ) = 0;


printf("%s ==== %s", value, string);

I noticed that sting will print in a new line, why this?

Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
"General Protection Fault" or something along those lines. The
anonymous array created by the string literal is not `const', but
that's just an accident of history. Trying to modify such an array
yields undefined behavior -- and indeed, plenty of compilers will
put the arrays in read-only memory. (This allows them to save space
by allocating just one array to hold both of "over" and "recover".)

If you want a modifiable string, use the literal as an initializer:

char string[] = "Simulated Annealing = 12847369";

This gives you an ordinary (named) array that you can modify at will,
initialized with the characters of the string literal.
char* karmarkar = "Karmarkar 958572";
I want to use strchr to find the first occurrence of "space" in string karmarkar.
How do I do that?

char *space = strchr(karmarkar, ' ');
if (space == NULL)
printf ("No spaces\n");
else
printf ("First space is at position %u\n",
(unsigned)(space - karmarkar));
 
S

sandeep

Eric said:
char *space = strchr(karmarkar, ' '); if (space == NULL)
printf ("No spaces\n");
else
printf ("First space is at position %u\n",
(unsigned)(space - karmarkar));

This could give the wrong answer on implementations where PTRDIFF_MAX >
UINT_MAX.
 
E

Eric Sosman

This could give the wrong answer on implementations where PTRDIFF_MAX>
UINT_MAX.

Thank you so very, very much for this helpful observation,
guaranteed to clarify matters for the O.P. Maybe I should have
written

printf ("First space is at position %g\n",
(double)(space - karmarkar));

.... but then I'm sure you'd point out that it might print the
wrong answer if the first space was more than 1E37 characters
(10000000000000000000000000000000000000 characters) into the
string, and would very likely print only an approximate answer
for many shorter strings. I await your enlightening disquisition
on this vital matter with great eagerness.
 
J

Joachim Schmitz

James said:
It's not 'const'.

Whatever, it is safe enough to assume them being const.
Attempting to write to it does have explicitly
undefined behavior, (6.4.5p6). However, that's completely separate
from the fact that attempting to write to an object defined with
'const' is undefined behavior (6.7.3p5).

The fact that the behavior is undefined doesn't mean that it "should
segfault".

I didn't mean "should" as a requirement from the standard, more a personal
wish.
If the standard did say that it "should segfault", that
would correspond to defining the behavior. In point of fact, one of
the single most common ways programs behave, when their behavior is
undefined, is in precisely the way their author inappropriately
expects them to behave.

bye, Jojo
 
J

Joachim Schmitz

Heinrich said:
Newsbeitrag ...

You are right! I missed that.

...

char * value = strstr(karmarkar, " ");
or
char * value = strchr(karmarkar, ' ');

Yes, of course, thanks for the correction.
My own correction to my post apparently didn't make it to the news server...

bye, Jojo
 
K

Keith Thompson

sandeep said:
This could give the wrong answer on implementations where PTRDIFF_MAX >
UINT_MAX.

If you're going to quote code, please keep the original formatting, or
at least odn't make it worse. Eric's code didn't have the declaration
and the if on the same line.
 
K

Keith Thompson

Joachim Schmitz said:
Whatever, it is safe enough to assume them being const.

Unless that assumption leads you to expect warnings from the compiler if
you try to modify it.

The best approach is to add const qualifiers to the declarations:

const char *string = "Simulated Annealing = 12847369";
const char *value = strchr(string, '=');

But again, the compiler won't warn you if you omit the "const".
 
S

sandeep

Eric said:
Thank you so very, very much for this helpful observation,
guaranteed to clarify matters for the O.P. Maybe I should have written

printf ("First space is at position %g\n",
(double)(space - karmarkar));

... but then I'm sure you'd point out that it might print the wrong
answer if the first space was more than 1E37 characters
(10000000000000000000000000000000000000 characters) into the string, and
would very likely print only an approximate answer for many shorter
strings. I await your enlightening disquisition on this vital matter
with great eagerness.

You are very welcome, Eric. I would say that it is actually quite a minor
point, but it's good not to get into bad habits!

I would advise using the %td format specifier for ptrdiff_t values: it is
generally better not to use double for integer values, but instead use a
large enough integer type (or a bignum library if the basic C types are
insufficient).

In C90 there is no ptrdiff_t, so casting to (signed long int) and using %
ld may be best. I don't know if pointer expressions in C90 are allowed to
yield wider types than long int.
 
K

Keith Thompson

sandeep said:
In C90 there is no ptrdiff_t, so casting to (signed long int) and using %
ld may be best. I don't know if pointer expressions in C90 are allowed to
yield wider types than long int.

Yes, C90 does have ptrdiff_t; see C90 7.1.6.

C90 doesn't have a printf conversion specifier for ptrdiff_t, but
converting to long should be enough; ptrdiff_t is a typedef for a
signed integer type, and C90 has no predefined signed type wider
than long.
 
S

Shao Miller

In C90 there is no ptrdiff_t, so casting to (signed long int) and using %
ld may be best. I don't know if pointer expressions in C90 are allowed to
yield wider types than long int.

Are you certain of that? I have a document which predates ANSI
X3.159-1989 (C89, right?) and which appears to include it.
 
S

Seebs

C90 doesn't have a printf conversion specifier for ptrdiff_t, but
converting to long should be enough; ptrdiff_t is a typedef for a
signed integer type, and C90 has no predefined signed type wider
than long.

Unfortunately, nearly every implementation now in use which is being used
in "C90" mode actually has "long long". With no stable way to print it...

*sigh*

-s
 
K

Keith Thompson

Seebs said:
Unfortunately, nearly every implementation now in use which is being used
in "C90" mode actually has "long long". With no stable way to print it...

*sigh*

But do any of them make ptrdiff_t (or any other predefined typedef)
wider than long? If not, then using "%ld" and a cast to long is
enough for this particular case. (And even if ptrdiff_t is wider
than long, it's only a problem if the actual value being printed
exceeds LONG_MAX.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,952
Messages
2,570,111
Members
46,692
Latest member
NewtonChri

Latest Threads

Top