Crash!!! 
Author Message
 Crash!!!

My program that is supposed to receive input in the form of
112.43 and output "One hundred and Twelve dollars and
Forty-Three Cents" crashes. Any help would be appreciated?

(This is NOT homework. It is a challenging exercise in the
book "C - How to program 3rd Ed. (Deitel & Deitel) p.349
exercise 8.38).

Code follows:
#include <stdio.h>
#include <string.h>

#define BUFFER 10

char *GetWord(char c)
{
 char *ret;

 switch(c)
 {
  case '0':ret = "zero";break;
  case '1':ret = "one";break;
  case '2':ret = "two";break;
  case '3':ret = "three";break;
  case '4':ret = "four";break;
  case '5':ret = "five";break;
  case '6':ret = "six";break;
  case '7':ret = "seven";break;
  case '8':ret = "eight";break;
  case '9':ret = "nine";break;
 };
 return ret;

Quote:
}

char *GetUnit(int now, int total)
{
 char *ret;
 switch(total)
 {
  case 0:

  break;
  case 1:

  break;
  case 2:

  break;
  case 7:
  if(now==0)ret = "thousand";
  if(now==1)ret = "hundred";
  if(now==2)ret = "tens";
      if(now==3)ret = "ones";
  break;

 };
return ret;

Quote:
}

int main()
{
char amount[BUFFER];
int i;
int len;
char *temp;

printf("Enter amount: ");
fflush(stdout);

fgets(amount, strlen(amount), stdin);

len = strlen(amount);

printf("\n%s",amount);
printf("\n%d",len);

for(i=0;i<len;i++)
{
 printf("Word: %s\n",GetWord(amount[i]));
 printf("Unit: %s\n",GetUnit(i,len));

Quote:
}
return 0;
}



Fri, 09 Jan 2004 18:53:36 GMT  
 Crash!!!



Quote:
> My program that is supposed to receive input in the form of
> 112.43 and output "One hundred and Twelve dollars and
> Forty-Three Cents" crashes. Any help would be appreciated?

> (This is NOT homework. It is a challenging exercise in the
> book "C - How to program 3rd Ed. (Deitel & Deitel) p.349
> exercise 8.38).

We would be glad to help even if it _was_ homework, because you
posted your attempt :-)

I won't bring up a working solution here (you said it is not
homework so I think you would prefer some hints and work it out
yourself :-).
If you try the following:
1) Turn the warning level of your compiler up as far as possible
2) replace the two definitions "char *ret;" with "char *ret = NULL;"
you will for sure be able to find the error yourself.
I have also put some hints into your code

Quote:

> Code follows:
> #include <stdio.h>
> #include <string.h>

> #define BUFFER 10

> char *GetWord(char c)
> {
>  char *ret;

What if c == '.' ?
What if c == '\n' ?
The warning my compiler issues points exactly to this problem

Quote:
>  switch(c)
>  {
>   case '0':ret = "zero";break;
>   case '1':ret = "one";break;
>   case '2':ret = "two";break;
>   case '3':ret = "three";break;
>   case '4':ret = "four";break;
>   case '5':ret = "five";break;
>   case '6':ret = "six";break;
>   case '7':ret = "seven";break;
>   case '8':ret = "eight";break;
>   case '9':ret = "nine";break;
>  };
>  return ret;
> }

> char *GetUnit(int now, int total)
> {
>  char *ret;
>  switch(total)
>  {
>   case 0:

>   break;
>   case 1:

>   break;
>   case 2:

>   break;
>   case 7:
>   if(now==0)ret = "thousand";
>   if(now==1)ret = "hundred";
>   if(now==2)ret = "tens";
>       if(now==3)ret = "ones";
>   break;

>  };
> return ret;
> }

Your GetUnit() is flawn - think it over again
I would first look if there is a decimal point and where it is and
calculate the units from there

- Show quoted text -

Quote:

> int main()
> {
> char amount[BUFFER];
> int i;
> int len;
> char *temp;

> printf("Enter amount: ");
> fflush(stdout);

> fgets(amount, strlen(amount), stdin);

> len = strlen(amount);

> printf("\n%s",amount);
> printf("\n%d",len);

Did you notice, that the two outputs from the printf()s above are
spaced _two_ lines ?
Where does the additional '\n' come from ?
Besides that I would in general place the '\n' at the end of the
format string

Quote:

> for(i=0;i<len;i++)
> {
>  printf("Word: %s\n",GetWord(amount[i]));
>  printf("Unit: %s\n",GetUnit(i,len));

> }
> return 0;
> }

 HTH

-- .
Robert Stankowic



Fri, 09 Jan 2004 19:32:59 GMT  
 Crash!!!

Quote:
>My program that is supposed to receive input in the form of
>112.43 and output "One hundred and Twelve dollars and
>Forty-Three Cents" crashes. Any help would be appreciated?

use a de{*filter*}, or at least state the kind of crash that takes place.

--
okay, have a sig then



Fri, 09 Jan 2004 19:25:00 GMT  
 Crash!!!


Quote:
>My program that is supposed to receive input in the form of
>112.43 and output "One hundred and Twelve dollars and
>Forty-Three Cents" crashes. Any help would be appreciated?

>(This is NOT homework. It is a challenging exercise in the
>book "C - How to program 3rd Ed. (Deitel & Deitel) p.349
>exercise 8.38).

...

Quote:
>int main()
>{
>char amount[BUFFER];
>int i;
>int len;
>char *temp;

>printf("Enter amount: ");
>fflush(stdout);

>fgets(amount, strlen(amount), stdin);

Here's one problem. strlen() tells you the length of a string. A string
is a null terminated sequence of characters held in a character array.
amount is a character array but no string has been written to it so
it is an error to call strlen() on it. What you want is the size of the
array, not the length of a string so:

 fgets(amount, sizeof amount, stdin);

Also you should check the return value of any file input function,
fgets() returns a null pointer if it fails.

Quote:
>len = strlen(amount);

Since fgets() writes a string to the array this strlen() call is
fine (assuming fgets() doesn't fail in which case it is another error).

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


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



Fri, 09 Jan 2004 22:08:55 GMT  
 Crash!!!

Quote:

> My program that is supposed to receive input in the form of
> 112.43 and output "One hundred and Twelve dollars and
> Forty-Three Cents" crashes. Any help would be appreciated?

> (This is NOT homework. It is a challenging exercise in the
> book "C - How to program 3rd Ed. (Deitel & Deitel) p.349
> exercise 8.38).

> Code follows:
> #include <stdio.h>
> #include <string.h>

> #define BUFFER 10

> char *GetWord(char c)
> {
>  char *ret;

>  switch(c)
>  {
>   case '0':ret = "zero";break;
>   case '1':ret = "one";break;
>   case '2':ret = "two";break;
>   case '3':ret = "three";break;
>   case '4':ret = "four";break;
>   case '5':ret = "five";break;
>   case '6':ret = "six";break;
>   case '7':ret = "seven";break;
>   case '8':ret = "eight";break;
>   case '9':ret = "nine";break;
>  };
>  return ret;
> }

I would probably use something more like:

const char *getWord (char c)
{
  static const char *words[] = {"zero", "one", "two", "three", "four",
                          "five", "six", "seven", "eight", "nine};

  c -= '0';
  assert (c >= 0 && c < 10);  /* Assuming #include <assert.h> */

  return words[c];

- Show quoted text -

Quote:
}

> char *GetUnit(int now, int total)
> {
>  char *ret;
>  switch(total)
>  {
>   case 0:

>   break;
>   case 1:

>   break;
>   case 2:

>   break;
>   case 7:
>   if(now==0)ret = "thousand";
>   if(now==1)ret = "hundred";
>   if(now==2)ret = "tens";
>       if(now==3)ret = "ones";
>   break;

>  };
> return ret;
> }

This is completely broken.  This doesn't handle any input that isn't
exactly 7 characters in length, and even for those values doesn't
necessarily output the correct result:  consider 123.567, or " 123.56".

You need more than the current location and the size of the string -
you need to determine where the decimal point is, and where NOW is in
relation to that decimal point.

You need to really rethink GetUnit().

Quote:

> int main()
> {
> char amount[BUFFER];
> int i;
> int len;
> char *temp;

> printf("Enter amount: ");
> fflush(stdout);

> fgets(amount, strlen(amount), stdin);

The strlen(amount) is very wrong.  strlen() counts the characters up
to the first '\0' - but amount currently contains indeterminate
values, so this invokes undefined behavior.  Use

fgets (amount, BUFFER, stdin) instead.

- Show quoted text -

Quote:

> len = strlen(amount);

> printf("\n%s",amount);
> printf("\n%d",len);

> for(i=0;i<len;i++)
> {
>  printf("Word: %s\n",GetWord(amount[i]));
>  printf("Unit: %s\n",GetUnit(i,len));

> }
> return 0;
> }

Micah

--
"But please remember that the sum of all skills totals up to
some constant in the end. So whenever someone shows all signs of
being a exceptionally skilled C-programmer, chances are that his
social skills are below average ..."         --willem veenhoven



Sat, 10 Jan 2004 02:55:20 GMT  
 Crash!!!


...

Quote:
>I would probably use something more like:

>const char *getWord (char c)
>{
>  static const char *words[] = {"zero", "one", "two", "three", "four",
>                          "five", "six", "seven", "eight", "nine};

Arguably a more useful const would be after the *. Or consider that
you don't really need an extra pointer array:

   static const char words[][6] = {"zero", "one", "two", "three", "four",
                           "five", "six", "seven", "eight", "nine};

Quote:
>  c -= '0';
>  assert (c >= 0 && c < 10);  /* Assuming #include <assert.h> */
>  return words[c];

To avoid possible overflow on c -= '0' better would be:

   assert (c >= '0' && c <= '9');  /* Assuming #include <assert.h> */
   return words[c-'0'];

Quote:
>}

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


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


Sat, 10 Jan 2004 19:00:34 GMT  
 Crash!!!

Quote:



> ...

> >I would probably use something more like:

> >const char *getWord (char c)
> >{
> >  static const char *words[] = {"zero", "one", "two", "three", "four",
> >                          "five", "six", "seven", "eight", "nine};

> Arguably a more useful const would be after the *. Or consider that
> you don't really need an extra pointer array:

>    static const char words[][6] = {"zero", "one", "two", "three", "four",
>                            "five", "six", "seven", "eight", "nine};

I prefer the other way; the const was intended to force the strings
pointed to to be treated as unchangeable (same for the return type of
getWord()).  I don't feel the need to const-qualify the pointers
themselves, since they are not accessible outside this function
(though I guess it wouldn't really /hurt/); and forcing the elements
of words to be 6 bytes in length could potentially waste (a little)
space,  and could also be dangerous if I misjudge the size of my
words.   That last part is more important when I        port this to
another
(human-spoken)  language or something :)

Quote:
> >  c -= '0';
> >  assert (c >= 0 && c < 10);  /* Assuming #include <assert.h> */
> >  return words[c];

> To avoid possible overflow on c -= '0' better would be:

>    assert (c >= '0' && c <= '9');  /* Assuming #include <assert.h>
>    */
>    return words[c-'0'];

> >}

Quite right.  I had overflow in mind, but for some reason had thought
that an overflow would guarantee that the assertion failed anyway -
obviously wrong, since a signed overflow produces an
implementation-defined  value or signal.

Micah

--
"*I* don't think you understand your question."
                                        -- Tom Plunket



Fri, 16 Jan 2004 14:54:06 GMT  
 Crash!!!

Quote:




> > ...

> > >I would probably use something more like:

> > >const char *getWord (char c)
> > >{
> > >  static const char *words[] = {"zero", "one", "two", "three", "four",
> > >                          "five", "six", "seven", "eight", "nine};

> > Arguably a more useful const would be after the *. Or consider that
> > you don't really need an extra pointer array:

> >    static const char words[][6] = {"zero", "one", "two", "three", "four",
> >                            "five", "six", "seven", "eight", "nine};

> I prefer the other way; the const was intended to force the strings
> pointed to to be treated as unchangeable (same for the return type of
> getWord()).  I don't feel the need to const-qualify the pointers
> themselves, since they are not accessible outside this function
> (though I guess it wouldn't really /hurt/); and forcing the elements
> of words to be 6 bytes in length could potentially waste (a little)
> space,  and could also be dangerous if I misjudge the size of my
> words.   That last part is more important when I        port this to
> another
> (human-spoken)  language or something :)

> > >  c -= '0';
> > >  assert (c >= 0 && c < 10);  /* Assuming #include <assert.h> */
> > >  return words[c];

> > To avoid possible overflow on c -= '0' better would be:

> >    assert (c >= '0' && c <= '9');  /* Assuming #include <assert.h>
> >    */
> >    return words[c-'0'];

> > >}

> Quite right.  I had overflow in mind, but for some reason had thought
> that an overflow would guarantee that the assertion failed anyway -
> obviously wrong, since a signed overflow produces an
> implementation-defined  value or signal.

Signed overflow is the paradigm of undefined behavior.

--
 pete



Sat, 17 Jan 2004 07:50:42 GMT  
 Crash!!!

Quote:

> > Quite right.  I had overflow in mind, but for some reason had thought
> > that an overflow would guarantee that the assertion failed anyway -
> > obviously wrong, since a signed overflow produces an
> > implementation-defined  value or signal.

> Signed overflow is the paradigm of undefined behavior.

Signed overflow doesn't /produce/ undefined behavior.

--
Computers are basically very fast idiots.



Sat, 17 Jan 2004 08:36:04 GMT  
 Crash!!!

Quote:


> > > Quite right.  I had overflow in mind, but for some reason had thought
> > > that an overflow would guarantee that the assertion failed anyway -
> > > obviously wrong, since a signed overflow produces an
> > > implementation-defined  value or signal.

> > Signed overflow is the paradigm of undefined behavior.

> Signed overflow doesn't /produce/ undefined behavior.

This quote is from the last public draft of either standard:
"An example of undefined behavior is the behavior on integer overflow."

--
 pete



Sat, 17 Jan 2004 09:21:35 GMT  
 Crash!!!

Quote:



> > Signed overflow doesn't /produce/ undefined behavior.

> This quote is from the last public draft of either standard:
> "An example of undefined behavior is the behavior on integer overflow."

Examples are not normative.
--
"The way I see it, an intelligent person who disagrees with me is
 probably the most important person I'll interact with on any given
 day."
--Billy Chambless


Sat, 17 Jan 2004 09:27:07 GMT  
 Crash!!!

Quote:




> > > Signed overflow doesn't /produce/ undefined behavior.

> > This quote is from the last public draft of either standard:
> > "An example of undefined behavior is the behavior on integer
> > overflow."

> Examples are not normative.

Is the behavior on integer overflow an example of undefined behavior?

--
 pete



Sat, 17 Jan 2004 09:48:11 GMT  
 Crash!!!

Quote:




> > > > Signed overflow doesn't /produce/ undefined behavior.

> > > This quote is from the last public draft of either standard:
> > > "An example of undefined behavior is the behavior on integer
> > > overflow."

> > Examples are not normative.

> Is the behavior on integer overflow an example of undefined behavior?

Good question.  Other than the "example" quoted, I see no justification in
the current standard.

Does it or doesn't it?  Enquiring minds want to know.

Is this a standard defect?
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm



Sat, 17 Jan 2004 11:11:28 GMT  
 Crash!!!

Quote:







> > > > > Signed overflow doesn't /produce/ undefined behavior.

> > > > This quote is from the last public draft of either standard:
> > > > "An example of undefined behavior is the behavior on integer
> > > > overflow."

> > > Examples are not normative.

> > Is the behavior on integer overflow an example of undefined behavior?

> Good question.  Other than the "example" quoted, I see no justification in
> the current standard.

> Does it or doesn't it?  Enquiring minds want to know.

The way I read it, arithmetic can't overflow. For example, "The result
of binary + is the sum of its operands."  However, converting a sum to a
signed result type is implementation defined: "Otherwise, the new type
is signed and the value cannot be represented in it; either the result
is implementation-defined or an implementation-defined signal is
raised."


Sat, 17 Jan 2004 13:04:37 GMT  
 Crash!!!

Quote:







> > > > > Signed overflow doesn't /produce/ undefined behavior.

> > > > This quote is from the last public draft of either standard:
> > > > "An example of undefined behavior is the behavior on integer
> > > > overflow."

> > > Examples are not normative.

> > Is the behavior on integer overflow an example of undefined behavior?

> Good question.  Other than the "example" quoted, I see no justification in
> the current standard.

> Does it or doesn't it?  Enquiring minds want to know.

From n869:

       6.5  Expressions

       [#5]  If  an  exception  occurs  during the evaluation of an
       expression (that is, if the  result  is  not  mathematically
       defined  or not in the range of representable values for its
       type), the behavior is undefined.

The final version changes "exception" to "exceptional condition", but
the meaning seems to be unchanged.

--



Sat, 17 Jan 2004 14:31:44 GMT  
 
 [ 24 post ]  Go to page: [1] [2]

 Relevant Pages 

1. DOA app crashes with a Kernel Crash on exit

2. Crash, always crashes!

3. Narrowed down plop plop crash crash I think.

4. DOA app crashes with a Kernel Crash on exit

5. Narrowed down plop plop crash crash I think.

6. Project Problems (Crash! Crash! Crash!)

7. THANKS A LOT. No more plop plop crash crash.

8. Plop plop crash crash o how irritating it is.

9. THANKS A LOT. No more plop plop crash crash.

10. Plop plop crash crash o how irritating it is.

11. MFC with managed Extension crashes on win98??

12. systray & explorer crash

 

 
Powered by phpBB® Forum Software