Am I doing this right? 
Author Message
 Am I doing this right?

I have some code I'd like for you all to look at and confirm that what
I'm doing is correct. It works fine on a DOS machine, but DOS can
sometimes "prevent" bad code from crashing.

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

#define MAX 5     /* Number of array elements */
#define BUFF 20  /* Buff size */

int main(void)
{
  char *ptr, *itm[MAX], buff[BUFF];
  register int x;
  int flag = 0;

/* Init array */
  for (x = 0; x < MAX; x++)
    itm[x] = 0;

  x = 0;
/* Main loop */
  while (!flag) {
    printf("Enter string: ");
    if (!fgets(buff, BUFF, stdin)) {
      fprintf(stderr, "Error receiving input.\n");
      exit(EXIT_FAILURE);
    } else if ((ptr = strchr(buff, '\n')) != 0) {
      *ptr = '\0';
    }
    if ((itm[x] = malloc(strlen(buff)+1)) == 0) {
      fprintf(stderr, "Out of memory.\n");
      exit(EXIT_FAILURE);
    } else {
      strcpy(itm[x++], buff);     /* Incremented after operation */
    }
    if (x >= MAX)
      flag = 1;
  }
/* Display and free array */
  for (x = 0; x < MAX; x++)
    if (itm[x]) {
      printf("%d.) %s\n", x, itm[x]);
      free(itm[x]);
    }
  return EXIT_SUCCESS;

Quote:
}

So is this the proper way to accomplish what I'm trying to do?
Thanks for your help.


Thu, 01 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

>I have some code I'd like for you all to look at and confirm that what
>I'm doing is correct. It works fine on a DOS machine, but DOS can
>sometimes "prevent" bad code from crashing.

DOS can prevent bad code from crashing? Since when? DOS is the epitome
of operating systems that do nothing to prevent bad code from
crashing the whole machine. :)

DOS can merely get out of the way, and let bad code appear to work
by fluke. Sometimes. :)

Anyway, is there any reason why you can't try your program on
a free operating system that supports memory protection? ;)

Quote:
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>

>#define MAX 5     /* Number of array elements */
>#define BUFF 20  /* Buff size */

>int main(void)
>{
>  char *ptr, *itm[MAX], buff[BUFF];
>  register int x;
>  int flag = 0;

>/* Init array */
>  for (x = 0; x < MAX; x++)
>    itm[x] = 0;

There is an easier way to do this; just write an initializer into
the declaration of itm:

        char *itm[MAX] = { 0 };

Done!

Quote:
>  x = 0;
>/* Main loop */
>  while (!flag) {
>    printf("Enter string: ");
>    if (!fgets(buff, BUFF, stdin)) {
>      fprintf(stderr, "Error receiving input.\n");

It's wrong to conclude that an error happened. The fgets function returns null
if an error occured or if the end of file was reached.  You can use ferror or
feof to distinguish which one happened.  In some systems, the user can cause
stdin to return end of file by pressing a special key; an error message would
be an inappropriate and surprising response to this action.

You should probably just bail out of the loop here with a break, so that your
program robustly accepts as a short input. The current value of x will then
record how many strings were input.

Instead of using x in the loop, use another variable, say n. THen
in your display loop which echoes back the input, loop x from
0 to 1-n instead of from 0 to MAX-1.

Also, 19 characters is a little short of a line of text. All kinds of
real-world text files have lines that are longer than 19 characters (such as
this article, for instance). If you are going to impose a hard limit on line
length, it's probably a good idea to at least make it something decently large,
like, say, 255 characters.

Quote:
>      exit(EXIT_FAILURE);
>    } else if ((ptr = strchr(buff, '\n')) != 0) {
>      *ptr = '\0';
>    }
>    if ((itm[x] = malloc(strlen(buff)+1)) == 0) {
>      fprintf(stderr, "Out of memory.\n");
>      exit(EXIT_FAILURE);
>    } else {
>      strcpy(itm[x++], buff);     /* Incremented after operation */

The increment takes place before strcpy is called. After the evaluations of
arguments, immediately before the function call, a sequence point occurs. It
doesn't matter in this case, but it would matter if a function were called
which could inspect or modify x.

Quote:
>    }
>    if (x >= MAX)
>      flag = 1;

The use of the flag is unnecessary, since you could remove it by a simple
code transformation; just change your loop guard to

        while (x < MAX)

Better yet, you can combine the initialization, test and increment
into one:

        for (x = 0; x < MAX; x++)

The flag is completely unnecessary. There are situations in which a flag may be
the test method; for example, if you want to break several levels out of a
nested loop (or nested switch within loop) without using goto.

Quote:
>  }
>/* Display and free array */
>  for (x = 0; x < MAX; x++)
>    if (itm[x]) {
>      printf("%d.) %s\n", x, itm[x]);
>      free(itm[x]);
>    }
>  return EXIT_SUCCESS;
>}

>So is this the proper way to accomplish what I'm trying to do?

That depends on what you are trying to do. If you want to write a program which
reads in exactly 5 lines of input and then echoes them back with numbering in
front of each line, or terminates with an error message if end of input is
reached or an input error occurs before five lines are input, and which
treats any line longer than 19 characters as two or more distinct lines, you
are on the right track.


Thu, 01 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

>>    } else {
>>      strcpy(itm[x++], buff);     /* Incremented after operation */

>The increment takes place before strcpy is called. After the evaluations of
>arguments, immediately before the function call, a sequence point occurs. It
>doesn't matter in this case, but it would matter if a function were called
>which could inspect or modify x.

Obviously I'm confused here. Could you or someone else please clarify
the difference between x++ and ++x in this and other contexts.
Thanks for your previous post Kaz...it helps a lot.


Thu, 01 Nov 2001 03:00:00 GMT  
 Am I doing this right?

:>>    } else {
:>>      strcpy(itm[x++], buff);     /* Incremented after operation */
:>
:>The increment takes place before strcpy is called. After the evaluations of
:>arguments, immediately before the function call, a sequence point occurs. It
:>doesn't matter in this case, but it would matter if a function were called
:>which could inspect or modify x.

: Obviously I'm confused here. Could you or someone else please clarify
: the difference between x++ and ++x in this and other contexts.

'x++' is an expression which returns the value of x, then increments x.
The problem is, when does it increment the value of x?  Answer, before the
next sequence point in the code.  Kaz has described one sequence point, the
relevant one here, but there are others; sequence points aren't an easy
concept to grasp, and are sometimes badly covered in the textbooks, but
the FAQ is a good starting point.

The expression '++x', by contrast, first increments x then returns its
value; again, this has to be completed before the next sequence point.

C's order of evaluation of expressions is often indeterminate; expressions
can be evaluated in one of several orders, provided that the evaluations
and their side-effects are complete before the next sequence point.  The
order must, of course, still follow that required by operator precedence.

The most common sequence point is ';' - others are the ',' operator,
outside a function call, the && and || operators, and the '?:' operator.

Will



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

<snip>

Quote:

> The most common sequence point is ';' - others are the ',' operator,
> outside a function call, the && and || operators, and the '?:' operator.

Except of course that you can have a , operator as a sequence point inside
a function call. Example follows, which I am hoping I have got right:

int foo(int bar)
{
  return bar;

Quote:
}

int baz(void)
{
  int i = 6;
  int j = 42;
  int k = 99;
  return foo((i = j, k));

Quote:
}

Of course, if you were to write code this way, you'd probably end up dying
prematurely at the hands of your colleagues. But it is possible.

--
Richard Heathfield

The bug stops here.



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

> Of course, if you were to write code this way, you'd probably end up dying
> prematurely at the hands of your colleagues. But it is possible.

Not true -- at least not true if I were one of the colleagues. Immediately
would not be a second too soon.  8-)

Morris Dovey
West Des Moines, Iowa USA



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

: <snip>
:>
:> The most common sequence point is ';' - others are the ',' operator,
:> outside a function call, the && and || operators, and the '?:' operator.
:>

: Except of course that you can have a , operator as a sequence point inside
: a function call. Example follows, which I am hoping I have got right:

Yes, it was clumsy wording; I should have said 'except when it is used
as a separator for function arguments or initializers'.

Will



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:


>>>    } else {
>>>      strcpy(itm[x++], buff);     /* Incremented after operation */

>>The increment takes place before strcpy is called. After the evaluations
of
>>arguments, immediately before the function call, a sequence point occurs.
It
>>doesn't matter in this case, but it would matter if a function were called
>>which could inspect or modify x.

>Obviously I'm confused here. Could you or someone else please clarify
>the difference between x++ and ++x in this and other contexts.

The difference between ++x and x++ is the value they return, and absolutely
not "when" the increment takes place.  Talking about the increment taking
place "before" or "after" other things is just a shorthand, or a metaphor,
if you like.  x++ gives you the old value of x, whereas ++x gives you the
new value of x.  x++ is what you want here.

When you use ++x _or_ x++ in a function call, the increment takes place
_before_ the function is called.  So your comment "incremented after
operation" is a little misleading.  This isn't at all significant in your
case, but it would matter if, for example, 'x' was a global variable and the
function you were calling looked at it.

(IMO code which depended on this property would be pretty revolting, but
there you go.)

Cheers,
Richard



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?


Quote:
>I have some code I'd like for you all to look at and confirm that what
>I'm doing is correct. It works fine on a DOS machine, but DOS can
>sometimes "prevent" bad code from crashing.

It is better to say that DOS is not very good at spotting when a
program has "crashed". The problem is that a crashed program can still
give the appearance of working.

<code snipped>

Quote:
>So is this the proper way to accomplish what I'm trying to do?

What were you trying to do?

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


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



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:




>:>>    } else {
>:>>      strcpy(itm[x++], buff);     /* Incremented after operation */
>:>
>:>The increment takes place before strcpy is called. After the evaluations of
>:>arguments, immediately before the function call, a sequence point occurs. It
>:>doesn't matter in this case, but it would matter if a function were called
>:>which could inspect or modify x.

>: Obviously I'm confused here. Could you or someone else please clarify
>: the difference between x++ and ++x in this and other contexts.

>'x++' is an expression which returns the value of x, then increments x.

Careful, this suggest an order of events which is not necessarily the case.
What x++ does is produce the initial value of x as its result and at
some unspecified time (which could be before or after) the value stored in
x is incremented by 1.

Quote:
>The problem is, when does it increment the value of x?  Answer, before the
>next sequence point in the code.

More specifically between the enclosing sequence points.

Quote:
> Kaz has described one sequence point, the
>relevant one here, but there are others; sequence points aren't an easy
>concept to grasp, and are sometimes badly covered in the textbooks, but
>the FAQ is a good starting point.

Often not covered at all.

Quote:
>The expression '++x', by contrast, first increments x then returns its
>value; again, this has to be completed before the next sequence point.

++x produces as its result the initial value of x plus 1. At some point
between the previous and next sequence point the value stored in x
is incremented by 1. IMO it is best to view the result and the
side-effect (i.e. changing the values stored in x) as essentially
independent.

Quote:
>C's order of evaluation of expressions is often indeterminate; expressions
>can be evaluated in one of several orders, provided that the evaluations
>and their side-effects are complete before the next sequence point.  The
>order must, of course, still follow that required by operator precedence.

>The most common sequence point is ';' - others are the ',' operator,
>outside a function call, the && and || operators, and the '?:' operator.

; isn't inherently a sequence point. However a sequence point is
defined at the end of every "full expression". ; does mark the end of many
full expressions but not all, e.g. if (x == 0) x = 1; contains two full
expressions and defined two sequence points. for (x = 0; x < 10; x++) { }
contains 3 full expressions and defines three sequence points.

Also there is a sequence point just before a function is called (but after
all arguments and the function designator have been evaluated).

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


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



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:



[...]

Quote:
> : Obviously I'm confused here. Could you or someone else please clarify
> : the difference between x++ and ++x in this and other contexts.

> 'x++' is an expression which returns the value of x, then increments x.

[...]

Quote:

> The expression '++x', by contrast, first increments x then returns its
> value; again, this has to be completed before the next sequence point.

Unfortunately, explanations like this sometimes cause the very confusion
you are trying to avoid. I think it would be better to avoid words like
"first ... then" when trying to explain this.

Both 'x++' and '++x' accomplish two things -- they increment x, and give
a value. x++ gives the (old) value of x, ++x gives the value of x+1.
None of these guarantee which will happen first, the 'increment' or the
'return of value'. All that is guaranteed is that they will give the
correct value, and the increment will happen somewhere between the
previous sequence point and the next.

--
Joe



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

> I have some code I'd like for you all to look at and confirm that what
> I'm doing is correct. It works fine on a DOS machine, but DOS can
> sometimes "prevent" bad code from crashing.

depends on what you're trying to achieve.  If you're trying to parse
lambda calculus expression? No

Quote:
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>

> #define MAX 5     /* Number of array elements */
> #define BUFF 20  /* Buff size */

> int main(void)
> {
>   char *ptr, *itm[MAX], buff[BUFF];
>   register int x;
>   int flag = 0;

> /* Init array */
>   for (x = 0; x < MAX; x++)
>     itm[x] = 0;

>   x = 0;
> /* Main loop */
>   while (!flag) {
>     printf("Enter string: ");
>     if (!fgets(buff, BUFF, stdin)) {
>       fprintf(stderr, "Error receiving input.\n");
>       exit(EXIT_FAILURE);
>     } else if ((ptr = strchr(buff, '\n')) != 0) {
>       *ptr = '\0';
>     }
>     if ((itm[x] = malloc(strlen(buff)+1)) == 0) {
>       fprintf(stderr, "Out of memory.\n");
>       exit(EXIT_FAILURE);
>     } else {
>       strcpy(itm[x++], buff);     /* Incremented after operation */
>     }
>     if (x >= MAX)
>       flag = 1;
>   }
> /* Display and free array */
>   for (x = 0; x < MAX; x++)
>     if (itm[x]) {
>       printf("%d.) %s\n", x, itm[x]);
>       free(itm[x]);
>     }
>   return EXIT_SUCCESS;
> }

> So is this the proper way to accomplish what I'm trying to do?
> Thanks for your help.

--
Phobophile

Homepages:
World of Hate: http://bounce.to/phobophile
Bolt Thrower: http://bounce.to/boltthrower
Altar:  http://browse.to/altar
Coversongs list: http://bounce.to/covers



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

> >I have some code I'd like for you all to look at and confirm that what
> >I'm doing is correct. It works fine on a DOS machine, but DOS can
> >sometimes "prevent" bad code from crashing.

> DOS can prevent bad code from crashing? Since when? DOS is the epitome
> of operating systems that do nothing to prevent bad code from
> crashing the whole machine. :)

DOS, lacking knowledge of any memory protection hardware, will silently
permit dereferencing a NULL pointer (virtually *any* pointer value, for that
matter).  Other OSes use the MMU to set up protection on undefined pages,
and better OSes in particular make the zero page unaddressable.

--
Richard Krehbiel, Kastle Systems, Arlington VA USA



Fri, 02 Nov 2001 03:00:00 GMT  
 Am I doing this right?

Quote:

> Obviously I'm confused here. Could you or someone else please clarify
> the difference between x++ and ++x in this and other contexts.

At http://www.eskimo.com/~scs/readings/autoincrement.990118.html
you will find a longish essay I posted on this topic back in January.

                                        Steve Summit



Sat, 03 Nov 2001 03:00:00 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Window Classes: Am I doing this right?

2. CMutex - Am I doing this right?

3. CMutex - am I doing this right?

4. Creating an NT service (am I doing the right thing?)

5. System.Threading.Timer , am I doing this correctly ?

6. Wot am I doing rong??

7. what am i doing wrong?

8. what am I doing wrong here?

9. What am I doing wrong?

10. What am I doing wrong?

11. WHAT AM I DOING WRONG?

12. what am i doing wrong!

 

 
Powered by phpBB® Forum Software