Why does this crash?

P

pkirk25

Hi all,

I'm learning C and trying to find characters in a string array. All my
efforts result in crashing programs. Can anyone see why?

#include <stdio.h>


int main()
{

char strArray[10] = {"abcdefg"};

int i;

int j = strlen(strArray);

for (i = 0; i < j; ++i)
{
char a = strArray;

if (a = 'c')
{

printf("%s\n", a);
return 0;
}
}



return 0;
}
 
R

Richard Heathfield

pkirk25 said:

char a = strArray;

if (a = 'c')


You mean:

if(a == 'c')
{

printf("%s\n", a);

You probably mean:

printf("%c\n", a);

It's crashing because you're treating a, a single char, as if it were a
pointer to the first in a whole bunch of char.
 
T

Tak-Shing Chan

pkirk25 said:

char a = strArray;

if (a = 'c')


You mean:

if(a == 'c')
{

printf("%s\n", a);

You probably mean:

printf("%c\n", a);

It's crashing because you're treating a, a single char, as if it were a
pointer to the first in a whole bunch of char.


... or printf("%s\n", strArray). Also, the OP was calling
strlen without a prototype (undefined behaviour).

Tak-Shing
 
E

Eric Sosman

pkirk25 said:
Hi all,

I'm learning C and trying to find characters in a string array. All my
efforts result in crashing programs. Can anyone see why?

#include <stdio.h>

int main()
{
char strArray[10] = {"abcdefg"};
int i;
int j = strlen(strArray);

for (i = 0; i < j; ++i)
{
char a = strArray;
if (a = 'c')
{
printf("%s\n", a);


It crashes here because the "%s" code requires that you
provide a matching string argument, but `a' is just a `char'
and not a string. A string is not a single `char', but an
array of `char', one of which has the value zero to mark the
string's end.

Two other points: The `if' statement doesn't do what you
probably intend (go back to your textbook and read about the
difference between the `=' and `==' operators), and you need
to #include the <string.h> header if you want to use strlen().
 
C

CBFalconer

Richard said:
pkirk25 said:

char a = strArray;

if (a = 'c')


You mean:

if(a == 'c')


You can avoid these problems by adapting the habit of putting the
constant first, i.e.:

if ('c' == a) ...

and the compiler will complain if you have only a single '='.

--
Some informative links:
< <http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>
 
P

pkirk25

Many thanks all. Its allowed me to proceed ot the point where Ic an
find what I want in a string but now it crashes when I try to extract
it to another string.

I've tried several approaches here and all bomb out. Where am I going
wrong please?

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[100] = {"Pointer to a confused guy"};
char strDst[100];

int a = 0;

for (a = 0; a < 5; ++a)
{
strcat(strDst, strLong[a]);
}
return 0;
}
 
J

Joe Wright

pkirk25 said:
Hi all,

I'm learning C and trying to find characters in a string array. All my
efforts result in crashing programs. Can anyone see why?

#include <stdio.h>
#include said:
int main() int main(void) is preferred.
{

char strArray[10] = {"abcdefg"};

int i;

int j = strlen(strArray);

for (i = 0; i < j; ++i)
{
char a = strArray;

if (a = 'c')

Surely not an assignment. You mean 'if (a == 'c')' don't you?
{

printf("%s\n", a);
I assume you want to print the string beginning with the 'c'.
See below.
return 0;
}
}



return 0;
}
Maybe this is what you mean?

#include <stdio.h>
#include <string.h>

int main(void)
{
char strArray[10] = {"abcdefg"};
int i;
int j = strlen(strArray);
for (i = 0; i < j; ++i) {
char a = strArray;
if (a == 'c') {
printf("%s\n", strArray+i);
return 0;
}
}
return 0;
}

Maybe not.
 
T

trm

pkirk25 said:
I've tried several approaches here and all bomb out. Where
am I going wrong please?

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[100] = {"Pointer to a confused guy"};

strLong contains a string of length 25.
char strDst[100];

strDst isn't a string. Exercise: why not? How would you
make it into a string? Trick question: what does it actually
contain? Why?
int a = 0;

for (a = 0; a < 5; ++a)
{
strcat(strDst, strLong[a]);

This line has three problems. First, strLong[a] is not of the
appropriate type for strcat(), so this shouldn't even compile
as it is written here. Second, as mentioned above, strDst
isn't a string; using C's string functions on things that aren't
strings generally means anything at all can (and eventually
will) happen. Third, assuming the first two errors are fixed,
you appear to be trying to stuff 116 chars into a 100 char
array. I trust it is obvious why that's bad.
 
C

CBFalconer

pkirk25 said:
Many thanks all. Its allowed me to proceed ot the point where Ic
an find what I want in a string but now it crashes when I try to
extract it to another string.

I've tried several approaches here and all bomb out. Where am I
going wrong please?

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[100] = {"Pointer to a confused guy"};
char strDst[100];

int a = 0;
for (a = 0; a < 5; ++a)
{
strcat(strDst, strLong[a]);
}
return 0;
}

The following fixes to avoid undefined behaviour may help.

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[100] = {"Pointer to a confused guy"};
char strDst[100] = ""; /* <-- Nota bene */
int a = 0;

while (strlen(strDst) + strlen(&strLong[++a]) + 1 < 100) {
putchar(a + '0');
strcat(strDst, &strLong[a]);
}
puts(strDst);
return 0;
}

--
Some informative links:
< <http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>
 
K

Keith Thompson

CBFalconer said:
Richard said:
pkirk25 said:

char a = strArray;

if (a = 'c')


You mean:

if(a == 'c')


You can avoid these problems by adapting the habit of putting the
constant first, i.e.:

if ('c' == a) ...

and the compiler will complain if you have only a single '='.

[...]

Yes, you can, but many people, including me, find that style almost
unbearably ugly.

Train yourself to read "=" as "assign" and "==" as "is equal to".
 
R

Richard Heathfield

Keith Thompson said:
CBFalconer said:
Richard said:
pkirk25 said:

<snip>

char a = strArray;

if (a = 'c')

You mean:

if(a == 'c')


You can avoid these problems by adapting the habit of putting the
constant first, i.e.:

if ('c' == a) ...

and the compiler will complain if you have only a single '='.

[...]

Yes, you can, but many people, including me, find that style almost
unbearably ugly.


Yes, they do, but many people, including me, don't. :)
Train yourself to read "=" as "assign" and "==" as "is equal to".

That's an excellent idea, although personally I prefer "becomes" over
"assign". Once you've done that, though, that doesn't mean you'll always
type what you meant to type. (And if you've *really* trained yourself to
read "==" as "is equal to", then surely it doesn't matter from a
readability perspective which way round they go.)

Incidentally, around 15 years ago I was debugging a production code bug
report. I spotted the following line merely in passing, as it were - it
wasn't the problem I was looking for, but it was nevertheless most
assuredly a problem:

k == 5;

(That was the exact code. I can't remember what k stood for, let alone 5.)

Unfortunately, no parallel trick of the language exists for forcing the
compiler to detect this kind of error.
 
J

jmcgill

Richard said:
k == 5;

(That was the exact code. I can't remember what k stood for, let alone 5.)

Unfortunately, no parallel trick of the language exists for forcing the
compiler to detect this kind of error.

I wonder if a warning about throwing away the result of a value
comparison would be very complicated to implement. Seems like something
of that nature *would* catch such a problem. But I realize there might
be something ugly about the grammar that I'm not considering.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said: [...]
Yes, you can, but many people, including me, find that style almost
unbearably ugly.

Yes, they do, but many people, including me, don't. :)

Fortunately, it's possible to avoid offending either of us simply by
doing it my way. :cool:}
That's an excellent idea, although personally I prefer "becomes" over
"assign". Once you've done that, though, that doesn't mean you'll always
type what you meant to type. (And if you've *really* trained yourself to
read "==" as "is equal to", then surely it doesn't matter from a
readability perspective which way round they go.)

It does matter.
 
F

Frederick Gotham

Keith Thompson posted:
Yes, you can, but many people, including me, find that style almost
unbearably ugly.


From my own experience, the vast majority of C programmers advocate it.
 
R

Richard Heathfield

jmcgill said:
I wonder if a warning about throwing away the result of a value
comparison would be very complicated to implement.

A good compiler will say something like "code has no effect". Unfortunately,
not all compilers are as helpful (and some that /are/, are all too often
invoked without the flags that free them from their self-imposed decision
not to be too noisy...).
 
F

Frederick Gotham

jmcgill posted:
I wonder if a warning about throwing away the result of a value
comparison would be very complicated to implement. Seems like something
of that nature *would* catch such a problem. But I realize there might
be something ugly about the grammar that I'm not considering.


On all of the compilers I've used lately, I explicitly have to cast to void
in order to suppress a compiler warning pertaining to a non-operation. For
instance, the following would produce a warning:

int main(void)
{
5==7;
return 0;
}

, while the following wouldn't:

int main(void)
{
(void)(5==7);
return 0;
}
 
R

Richard Heathfield

Keith Thompson said:
It does matter.

If it matters because you expect the constant to be in a certain position
and are surprised when it is not, rest assured that I, too, expect the
constant to be in a certain position and am surprised when it is not. So,
for you, it matters that we write if(v == C), and for me it matters that we
write if(C == v). Oh well. If we ever end up working on the same project, I
guess we'll have to come up with a compromise - i.e. a solution that
pleases nobody but which gives everyone the satisfying feeling that the
other fellow didn't get his way either.

How about if(!(v != C)) ? :)
 
F

Frederick Gotham

Richard Heathfield posted:
If it matters because you expect the constant to be in a certain
position and are surprised when it is not, rest assured that I, too,
expect the constant to be in a certain position and am surprised when it
is not.


Yes, but your expectation to see the constant on the left-hand side of the
equality operator is purely out of habit and conditioning, and nothing to do
with any inherent meaning or understanding. The situation is not like a more
inherent idea like handness, whereby a baby is predisposed to favouring one
hand over another, a predisposition which can't be changed by yanking the
crayon out of their hand and placing it in the other hand. Quite the
contrary, this whole "C==v" business is simply a habit, like writing
"unsigned char" instead of "char unsigned".

The people who favour:

constant == variable

argue that it is less prone to typos. The people who argue:

variable == constant

argue little more than that you can't teach an old dog new tricks.

So, for you, it matters that we write if(v == C), and for me it
matters that we write if(C == v).


I consciously write C==v for the reason cited above. I find it superior. If
I'm reading other people's code however, I don't even pay attention to their
style, I just extract the meaning regardless of whether they write "i++"
instead of "++i", or "char unsigned" instead of "unsigned char", or "int
const *" instead of "const int*". Thankfully my knowledge of the C Standard
allows me to interpret any grammatically correct code, irrespective of
whether it differs from my own grammar usage.

Oh well. If we ever end up working on the same project, I guess we'll
have to come up with a compromise - i.e. a solution that pleases nobody
but which gives everyone the satisfying feeling that the other fellow
didn't get his way either.


I think it would be better to train your mind for dealing with variance,
whether it be hearing someone say "tomAto" instead of "toMAYto", or writing
"v==C" instead of "C==v". The reason you find the latter to be ugly is
because it's horribly alien to you and it's far removed from what you've been
accustomed to for a great deal of time. Don't mask the symptoms, kill the
infection -- there's nothing wrong with "C==v" except your attitude to it,
and so you would be better to get used to it rather than grimacing every time
you encounter it.
 
B

bitshadow

for your first post:
#include <stdio.h>

int main()
{
/*don't need 10 char. let the compiler allocate for you*/
char strArray[] = {"abcdefg"};

int i;

int j = strlen(strArray);

for (i = 0; i < j; ++i)
{
char a = strArray;
if (a == 'c')/*if a = 'c' means if a gets c. a==c means
if a is c*/
{

printf("%c\n", a);/*don't want to print a
string you want to
print a character. show the correct specifier*/
getchar();
return 0;
}
}
/*don't think you really need this could have simple exited from the
firsr loop*/
getchar();
return 0;
}

for your second post:

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[] = {"Pointer to a confused guy"};
char strDst[100];

int a;

for (a = 0; a < 5; ++a)
/*want to cat to dst the contest of strlong up to 5
characters*/
{
strcat(strDst, strLong);/*prolly want strcpy*/
/*print to strDst to make sure copied*/
}
getchar();
return 0;
}
Notice i modified some of your code. let me know if you don't see why.
 
J

Joe Wright

bitshadow said:
for your first post:
#include <stdio.h>

int main()
{
/*don't need 10 char. let the compiler allocate for you*/
char strArray[] = {"abcdefg"};

int i;

int j = strlen(strArray);

for (i = 0; i < j; ++i)
{
char a = strArray;
if (a == 'c')/*if a = 'c' means if a gets c. a==c means
if a is c*/
{

printf("%c\n", a);/*don't want to print a
string you want to
print a character. show the correct specifier*/
getchar();
return 0;
}
}
/*don't think you really need this could have simple exited from the
firsr loop*/
getchar();
return 0;
}

for your second post:

#include <stdio.h>
#include <string.h>

int main(void)
{
char strLong[] = {"Pointer to a confused guy"};
char strDst[100];

int a;

for (a = 0; a < 5; ++a)
/*want to cat to dst the contest of strlong up to 5
characters*/
{
strcat(strDst, strLong);/*prolly want strcpy*/
/*print to strDst to make sure copied*/
}
getchar();
return 0;
}
Notice i modified some of your code. let me know if you don't see why.

I didn't write any of the stuff you attribute to me. Please be more
careful in the future.
 

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,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top