New to C: Getting Application error when running program

M

Mike Polinske

I am new to the C programming language but have been programming in
Cobol for over 10 years. When I compile the following code, it
compiles clean but I get an application error both under Windows XP and
Win2K.

#include <stdio.h>
#include <ctype.h>

char title[] = "Year End Report";

char work_buffer[51];

main()
{
strcpy(work_buffer,title);
strncenter(work_buffer,50);
printf("%s\n",work_buffer);
strljust(work_buffer);
printf("%s\n",work_buffer);
strrjust(work_buffer);
printf("%s\n",work_buffer);
}

/* Left justify a string */
strljust(str)
char *str;
{
int len;

len = strlen(str);
while (isspace(str) != 0) {
memmove (str,str + 1,len);
str[len] = ' ';
}
}

/* Reverse a string */
strrev(str)
char *str;
{
char ch;
char *end;

end = str + strlen(str) - 1;

while (str < end) {
ch = *end;
*end-- = *str;
*str++ = ch;
}
}

/* Right justify a string */
strrjust(str)
char *str;
{
strrev(str);
strljust(str);
strrev(str);
}

/* Truncate to last non-white character */
strtrunc(str)
char *str;
{
char *end;

end = str + strlen(str) - 1;

while ((*str != 0) && (isspace (*end) != 0)) {
*end-- = 0;
}
}

/* Pad a string for len with spaces */
struntrunc(str,len)
char *str;
int len;
{
while (strlen (str) < len) {
strcat (str,' ');
}
}

/* Center a string */
strcenter(str)
char *str;
{
strncenter (str, strlen(str));
}

/* Center a string within width */
strncenter(str,width)
char *str;
int width;
{
int non_blank_len, padding;

strtrunc (str);
strrev (str);
strtrunc (str);
non_blank_len = strlen (str);

padding = (width - non_blank_len) / 2;

struntrunc (str,padding);
strrev (str);
struntrunc (str,width);
}

It seems to be blowing up in the struntrunc function, but I can't
understand why. I know that this program is trying to take a string,
center it, left justify it and right justify it.

Any ideas on how I can get this program to run?

I am using Open Watcom C/C++ 1.4 but I had the same problem when I
tried it with OW 1.3.

Thanks
 
L

lothar.behrens

Be sure, there will be no buffer overrun. Try a buffer with 52 or some
more chars.

Yust a thought :)

Lothar
 
M

Mark McIntyre

compiles clean but I get an application error both under Windows XP and
Win2K.

Turn warninglevels up to max on your compiler. There are several
coding errors that ought to have been alerted to you.
#include <stdio.h>
#include <ctype.h>

char title[] = "Year End Report";
char work_buffer[51];

no need for these to be globals, they can be inside main.
main()
{
strcpy(work_buffer,title);

you should get a warning from your compiler here - you need a
declaration of strcpy() in scope, usually provided by #include
strncenter(work_buffer,50);

you have the same problem here. Put a prototype for strncenter()
before the start of main.

Also, its a bad idea to name functions str followed by a lower case
letter. Such names are reserved for the compiler. strCenter would be
ok tho, or str_center.
printf("%s\n",work_buffer);
strljust(work_buffer);
printf("%s\n",work_buffer);
strrjust(work_buffer);
printf("%s\n",work_buffer);
}

/* Left justify a string */
strljust(str)
char *str;

this style of function definition is 20 years out of date. The normal
modern style is
void strladjust(char *str)

There's two differences here - firstly your original function was
implicitly returning an int, which is permissible but deprecated ;
secondly, you should include the parameter type in the parens.

Also, a function must return something, unless its declared void.
Yours is declared as returning an int, but doesn't return anything.
Oops!
{
int len;

len = strlen(str);
while (isspace(str) != 0) {

isspace() expects a single character - str is a string.
Did you mean *str. ?
memmove (str,str + 1,len);
str[len] = ' ';
}
}

/* Reverse a string */
strrev(str)
char *str;

this name may conflict with a builtin library function. Did this
actually compile?
struntrunc(str,len)
char *str;
int len;
{
while (strlen (str) < len) {
strcat (str,' ');

strcat requires the 2nd parameter to be a string, not a char.
strcat(str, " ");

by the way, one can do this entire operation much more simply with
sprintf()

Mark McIntyre
--
 
F

Flash Gordon

Mike said:
I am new to the C programming language but have been programming in
Cobol for over 10 years. When I compile the following code, it
compiles clean but I get an application error both under Windows XP and
Win2K.

#include <stdio.h>
#include <ctype.h>

char title[] = "Year End Report";

char work_buffer[51];

main()

Main returns an int, and as you are not using the optional parameters it
is better to say so explicitly.

int main(void)
{
strcpy(work_buffer,title);
strncenter(work_buffer,50);
printf("%s\n",work_buffer);
strljust(work_buffer);
printf("%s\n",work_buffer);
strrjust(work_buffer);
printf("%s\n",work_buffer);

Main returns an int, so return an int!
return 0;
}

/* Left justify a string */
strljust(str)
char *str;

Replace whatever resource you are learning from. That style went out in
1989. Use the prototype style instead

strljust(char *str)

Also, add a prototype definition before main so that the compiler is
required to validate the parameters.

Also, function names starting str followed by a lower case letter are
reserved, so you should pick a different name. Possibly str_ljust.
{
int len;

len = strlen(str);
while (isspace(str) != 0) {

Why not simply
while (isspace(str))
?
memmove (str,str + 1,len);
str[len] = ' ';

C arrays are indexed from 0 not from 1, so this is your problem. You are
overwriting the null termination of the string instead of the last
non-null character.

Also, why not work out how far you need to move it then move it all the
way in one go? I know we say don't optimise until you know you have a
problem, but there is no need to go overboard and make it obviously
inefficient!
}

/* Reverse a string */
strrev(str)
char *str;

Same comments as before.
{
char ch;
char *end;

end = str + strlen(str) - 1;

while (str < end) {
ch = *end;
*end-- = *str;
*str++ = ch;
}
}

/* Right justify a string */
strrjust(str)
char *str;

Same comments.
{
strrev(str);
strljust(str);
strrev(str);
}

/* Truncate to last non-white character */
strtrunc(str)
char *str;

Same comments again.

It seems to be blowing up in the struntrunc function, but I can't
understand why. I know that this program is trying to take a string,
center it, left justify it and right justify it.

Any ideas on how I can get this program to run?

First fix everything I (and anyone else who responds) have pointed out,
then go through the code looking for any other similar errors. I've
you've made a given class of mistakes once yoy may well have made it
more than once.
I am using Open Watcom C/C++ 1.4 but I had the same problem when I
tried it with OW 1.3.

On comp.lang.c the compiler is irrelevant since we only deal with
standard C. However, your problem looks to be with standard C rather
than the compiler, so it is perfectly on topic in comp.lang.c
 
R

Roberto Waltman

I am new to the C programming language but have been programming in
Cobol for over 10 years. When I compile the following code, it
compiles clean but I get an application error both under Windows XP and
Win2K.


In addition to what others pointed out re: "old style" declarations,
these are the few errors I can see:

#include <stdio.h>
#include <ctype.h>

char title[] = "Year End Report";

char work_buffer[51];

main()
{
strcpy(work_buffer,title);
strncenter(work_buffer,50);
printf("%s\n",work_buffer);
strljust(work_buffer);
printf("%s\n",work_buffer);
strrjust(work_buffer);
printf("%s\n",work_buffer);
}

/* Left justify a string */
strljust(str)
char *str;
{
int len;

len = strlen(str);
while (isspace(str) != 0) {
%%%%%% should be isspace(*str) - isspace expects a char, not a pointer
to one
memmove (str,str + 1,len);
str[len] = ' ';
}
}

/* Reverse a string */
strrev(str)
%%%%%% strrev is already defined. choose another name
char *str;
{
char ch;
char *end;

end = str + strlen(str) - 1;

while (str < end) {
ch = *end;
*end-- = *str;
*str++ = ch;
}
}

/* Right justify a string */
strrjust(str)
char *str;
{
strrev(str);
strljust(str);
strrev(str);
}

/* Truncate to last non-white character */
strtrunc(str)
char *str;
{
char *end;

end = str + strlen(str) - 1;

while ((*str != 0) && (isspace (*end) != 0)) {
*end-- = 0;
}
}

/* Pad a string for len with spaces */
struntrunc(str,len)
char *str;
int len;
{
while (strlen (str) < len) {
strcat (str,' ');
%%%%%% should be strcat(str, " "); - strcat() expects two strings
}
}

/* Center a string */
strcenter(str)
char *str;
{
strncenter (str, strlen(str));
}

/* Center a string within width */
strncenter(str,width)
char *str;
int width;
{
int non_blank_len, padding;

strtrunc (str);
strrev (str);
strtrunc (str);
non_blank_len = strlen (str);

padding = (width - non_blank_len) / 2;

struntrunc (str,padding);
strrev (str);
struntrunc (str,width);
}

It seems to be blowing up in the struntrunc function, but I can't
understand why. I know that this program is trying to take a string,
center it, left justify it and right justify it.
Roberto Waltman

[ Please reply to the group, ]
[ return address is invalid. ]
 
P

pete

Mike said:
I am new to the C programming language but have been programming in
Cobol for over 10 years. When I compile the following code, it
compiles clean but I get an application error both under Windows XP and
Win2K.

#include <stdio.h>
#include <ctype.h>

char title[] = "Year End Report";

char work_buffer[51];

main()
{
strcpy(work_buffer,title);
strncenter(work_buffer,50);
printf("%s\n",work_buffer);
strljust(work_buffer);
printf("%s\n",work_buffer);
strrjust(work_buffer);
printf("%s\n",work_buffer);
}

/* Left justify a string */
strljust(str)
char *str;
{
int len;

len = strlen(str);
while (isspace(str) != 0) {
memmove (str,str + 1,len);
str[len] = ' ';
}
}

/* Reverse a string */
strrev(str)
char *str;
{
char ch;
char *end;

end = str + strlen(str) - 1;

while (str < end) {
ch = *end;
*end-- = *str;
*str++ = ch;
}
}

/* Right justify a string */
strrjust(str)
char *str;
{
strrev(str);
strljust(str);
strrev(str);
}

/* Truncate to last non-white character */
strtrunc(str)
char *str;
{
char *end;

end = str + strlen(str) - 1;

while ((*str != 0) && (isspace (*end) != 0)) {
*end-- = 0;
}
}

/* Pad a string for len with spaces */
struntrunc(str,len)
char *str;
int len;
{
while (strlen (str) < len) {
strcat (str,' ');
}
}

/* Center a string */
strcenter(str)
char *str;
{
strncenter (str, strlen(str));
}

/* Center a string within width */
strncenter(str,width)
char *str;
int width;
{
int non_blank_len, padding;

strtrunc (str);
strrev (str);
strtrunc (str);
non_blank_len = strlen (str);

padding = (width - non_blank_len) / 2;

struntrunc (str,padding);
strrev (str);
struntrunc (str,width);
}

It seems to be blowing up in the struntrunc function, but I can't
understand why. I know that this program is trying to take a string,
center it, left justify it and right justify it.

Any ideas on how I can get this program to run?

/* BEGIN new.c */

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

void str_ljust(char *str);
void str_rev(char *str);
void str_rjust(char *str, size_t len);
void str_trunc(char *str);
void str_untrunc(char *str, size_t len);
void str_center(char *str);
void str_ncenter(char *str, size_t len);

int main(void)
{
char title[] = " Year End Report ";
char work_buffer[51];

strcpy(work_buffer, title);

str_ncenter(work_buffer, 50);
printf("%s\n",work_buffer);

str_ljust(work_buffer);
printf("%s\n", work_buffer);

str_rjust(work_buffer, 50);
printf("%s\n", work_buffer);

return 0;
}

void str_ljust(char *str)
{
char *ptr = str;

while (isspace(*ptr)) {
++ptr;
}
memmove(str, ptr, strlen(ptr) + 1);
}

void str_rev(char *str)
{
char ch;
char *end;

if (str[0] != '\0') {
end = str + strlen(str + 1);
while (str < end) {
ch = *end;
*end-- = *str;
*str++ = ch;
}
}
}

void str_rjust(char *str, size_t len)
{
size_t pad;

str_rev(str);
str_trunc(str);
str_rev(str);
str_trunc(str);
pad = len - strlen(str);
memmove(str + pad, str, strlen(str) + 1);
memset(str, ' ', pad);
}

void str_trunc(char *str)
{
char *end = str + strlen(str);

while (end != str && isspace(*--end)) {
*end = '\0';
}
}

void str_untrunc(char *str, size_t len)
{
memset(str + strlen(str), ' ', len - strlen(str));
str[len] = '\0';
}

void str_center(char *str)
{
str_ncenter (str, strlen(str));
}

void str_ncenter(char *str, size_t len)
{
size_t pad;

str_rev(str);
str_trunc(str);
str_rev(str);
str_trunc(str);
pad = (len - strlen(str)) / 2;
memmove(str + pad, str, strlen(str) + 1);
memset(str, ' ', pad);
}

/* END new.c */
 
M

Mike Polinske

Thank you everyone!!

I am using a book called "Moving from Cobol to C" by Mo Budlong which
is from 1993.

I thought it would be good to start with this book rather than K&R's C
Programming, but I guess I was wrong :)

I didn't realize C had changed that much and I had ignored the compiler
warnings about no prototypes. I also thought that since C++ is derived
from C I would start out with C programming.

Coming from the nice "wordiness" of Cobol, C and C++ feel like a bunch
of shorthand or hieroglyphics :)

I'm going to keep on trying to learn C and C++ since I'd like to expand
my programming language knowledge.
 
F

Flash Gordon

Mike said:
Thank you everyone!!

I am using a book called "Moving from Cobol to C" by Mo Budlong which
is from 1993.

It looks like that book was out of date even when it was written. The C
standard which introduced prototypes came out in 1989!
I thought it would be good to start with this book rather than K&R's C
Programming, but I guess I was wrong :)

You were. You would be far better off starting with K&R.
I didn't realize C had changed that much and I had ignored the compiler
warnings about no prototypes.

Never ignore warnings because they almost always indicate that you
really do have a problem.
> I also thought that since C++ is derived
from C I would start out with C programming.

Yes, learning C before C++ is reasonable.
Coming from the nice "wordiness" of Cobol, C and C++ feel like a bunch
of shorthand or hieroglyphics :)

I'm going to keep on trying to learn C and C++ since I'd like to expand
my programming language knowledge.

Just remember that although C++ was derived from C in the early days the
languages have diverged significantly so things which are good style in
C are errors in C++ and vice versa.
 
R

Richard Bos

Flash Gordon said:
Never ignore warnings because they almost always indicate that you
really do have a problem.

But also do note that warnings do not always point out exactly the
problem that the text of the warning seems to indicate. One infamous
warning is the one about "converting integer to pointer without a cast",
which most usually does _not_ indicate that you're missing a cast, but
that you've forgot to #include the required header which would tell the
compiler that there is no integer to convert.

Richard
 
D

Default User

Flash said:
Mike Polinske wrote:

Yes, learning C before C++ is reasonable.

The C++ people tend to disagree with this. I would generally agree that
if you only want to learn C++, then start with it. I don't agree with
them that C is a handicap to learning C++, not if one chooses a proper
introductory book for that language.

If you'd like to become at least familiar with both languages, then C
is probably the better starting point, as it's a smaller language.
Just remember that although C++ was derived from C in the early days
the languages have diverged significantly so things which are good
style in C are errors in C++ and vice versa.

And some things that are good style in C are permissible in C++, but
not the optimal way to do things.


Brian
 
H

Hans-Bernhard Broeker

Roberto said:
%%%%%% should be isspace(*str) - isspace expects a char, not a pointer
to one

Nice try, but still incorrect. isspace takes an int, not a char, and
that int has to hold the unsigned value of the character in question,
which means that has to become

while(isspace((unsigned char) *str) !=0) {

Or, since the test !=0 is completely superfluous in C:

while(isspace((unsigned char) *str)) {

To the OP: yes, you need to get a less braindead C textbook. For people
who already know programming in general, K&R2 would be my recommendation.
 
H

Hans-Bernhard Broeker

Mike said:
I am using a book called "Moving from Cobol to C" by Mo Budlong which
is from 1993.
I didn't realize C had changed that much

C actually hasn't changed all that much since 1993 --- the problem with
that book is that it had already fallen several years behind its time
back when it came out. Adding 12 years didn't exactly help solve that
problem, obviously, but neither is it responsible for the bulk of it.
 
K

Keith Thompson

Hans-Bernhard Broeker said:
C actually hasn't changed all that much since 1993 --- the problem
with that book is that it had already fallen several years behind its
time back when it came out. Adding 12 years didn't exactly help solve
that problem, obviously, but neither is it responsible for the bulk of
it.

To be fair, I think there were still a number of pre-ANSI compilers in
use back in 1993. Some ANSI compilers were available, but code using
prototypes wasn't really portable unless you used a tool like
ansi2knr.
 
P

Peter C. Chapin

The C++ people tend to disagree with this. I would generally agree that
if you only want to learn C++, then start with it. I don't agree with
them that C is a handicap to learning C++, not if one chooses a proper
introductory book for that language.

As an instructor who teaches both C and C++ I concur with this. Some in the
C++ community feel that learning C teaches "bad habits" (due to C's
limitations) that one must work to unlearn in C++. There is some truth to
that. However many of the issues students have difficulty with in C (such
as pointers) must also be mastered when learning C++ anyway. Dealing with
those issues in a smaller language with fewer distracting and interacting
features is often easier than trying to learn them on top of everything
else in C++.

However, the argument I use in favor of learning C first and then C++ is
that by doing so you understand better where C leaves off and C++ begins.
That way when you are working in an environment that only offers C you have
a better idea of what you can (and can't) do. C and C++ are different
languages but they have an unusually intimate relationship. It is often
helpful, I believe, to have a clear idea about the boundary between them.

Peter
 
M

Michal Necasek

Peter said:
As an instructor who teaches both C and C++ I concur with this. Some in the
C++ community feel that learning C teaches "bad habits" (due to C's
limitations) that one must work to unlearn in C++. There is some truth to
that. However many of the issues students have difficulty with in C (such
as pointers) must also be mastered when learning C++ anyway. Dealing with
those issues in a smaller language with fewer distracting and interacting
features is often easier than trying to learn them on top of everything
else in C++.
Perhaps this will give people some idea of relative complexity of the
languages:

The ISO C90 standard had roughly 200 pages.

The ISO C99 standard has roughly 550; however, about 350 pages are
devoted solely to the library.

The ISO C++98 standard has roughly 770 pages, *however* it refers to
the ISO C standard for Standard C library description - otherwise it'd
be about 1,100 pages.

While this is not a good measure of complexity, it should be obvious
that with several times as many pages in the Standard, the language is
going to be significantly more complex.


Michal
 
R

Roald Ribe

My 2 cents worth:

It depends on how much and what type of development you are
going to do. I learned procedural languages first (basic,
pascal and c), that gave me serious disadvantages when
trying to think/learn object-oriented Java & others.
I do not think that either C or C++ are good learning
(first) languages. Go with Java or C# as a first language
since thar will be (IMO) much more productive (easy to learn),
and learn C/C++ later when/if the need arises.

Roald
 
C

CBFalconer

Michal said:
Perhaps this will give people some idea of relative complexity of
the languages:

The ISO C90 standard had roughly 200 pages.

The ISO C99 standard has roughly 550; however, about 350 pages are
devoted solely to the library.

The ISO C++98 standard has roughly 770 pages, *however* it refers
to the ISO C standard for Standard C library description -
otherwise it'd be about 1,100 pages.

While this is not a good measure of complexity, it should be
obvious that with several times as many pages in the Standard, the
language is going to be significantly more complex.

It is not just the complexity, but the organization of the
language. Extended Pascal (ISO10206) is roughly comparable to C99,
but the standard comprises about 230 pages. Pascal does not
contain the multiple reuses of symbols, nor the complex
precedences, etc. The library is much better organized, because it
was designed, rather than just grew.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
M

Michal Necasek

Roald said:
I do not think that either C or C++ are good learning
(first) languages. Go with Java or C# as a first language
since thar will be (IMO) much more productive (easy to learn),
and learn C/C++ later when/if the need arises.
I agree that C (let alone C++) is not easy for people who don't know
any programming. Heck, even experienced programmers sometimes have
trouble sorting out the finer points of pointer usage. However, I highly
doubt that Java and C# are any better. The first 'serious' programming
language I learned was Pascal, and in retrospect I can say that it was
an excellent language for learning (not surprising, as that's exactly
what it was designed for).

What many people apparently fail to realize is that object-oriented
programming is largely a question of application design, not nuts and
bolts programming. To learn programming basics like variables, arrays,
structures, expressions, loops, subroutines, etc. etc., all the object
oriented cruft just gets in the way. In other words, both Java and C# as
a first language violate the KISS principle.

It is possible that a scripting language might be good for learning
protramming these days, although the typeless coding those languages
promote might give a beginner some very bad habits.


Michal
 
R

Roald Ribe

Michal said:
I agree that C (let alone C++) is not easy for people who don't know
any programming. Heck, even experienced programmers sometimes have
trouble sorting out the finer points of pointer usage. However, I highly
doubt that Java and C# are any better.

Well, at least they do not have pointers ;-)
The first 'serious' programming
language I learned was Pascal, and in retrospect I can say that it was
an excellent language for learning (not surprising, as that's exactly
what it was designed for).

Yes but it is (was?) too limited for larger projects, unlike Java
and possibly C#. My point was also that if they will program in OO
languages in the future it is probably best to learn that way of
thinking about the peoblems and solutions right away.
What many people apparently fail to realize is that object-oriented
programming is largely a question of application design, not nuts and
bolts programming. To learn programming basics like variables, arrays,
structures, expressions, loops, subroutines, etc. etc., all the object
oriented cruft just gets in the way. In other words, both Java and C# as
a first language violate the KISS principle.

I disagree. In object oriented design and thinking everything is an
object. That some partially object oriented languages does not reflect
that (mostly for efficiency purposes) should not affect such a discussion.
Expressions, flowcontrol and arrays is mostly the same in object oriented
and procedural laguages, just about everything else is different.

All the "object oriented cruft" (he he) is only that if your only goal
is efficiency in executables, and "real" programming is assembly.
If the goal is correctness of the program in as short development
(or learning) cycle as possible, there is no doubt that Java and
others is better for that than C (using languages I know best
for comparison). Most programmers will never need to care about how
a character is represented in a RAM chip.
It is possible that a scripting language might be good for learning
protramming these days, although the typeless coding those languages
promote might give a beginner some very bad habits.

It all depends on what people are going to do. Not many percent of
the people who gets into programming will ever get a chance to make
a device driver or embedded sowtware or low level stuff like that.
Most will end up making software shuffling SQL data around in one
way or another. Who knows if we really need to learn more than a
scripting language for such a task?

Roald
 
M

Michal Necasek

Roald said:
Yes but it is (was?) too limited for larger projects, unlike Java
and possibly C#.
>
But isn't that the whole point? That a learning language should be
simple? Because otherwise, there's really no reason not to start with
C++. If anything, it's less limited for large projects than Java or C#.
I disagree. In object oriented design and thinking everything is an
object.
>
But everything isn't an object. Or, if you make it one, all you'll get
is lots of extra complexity and a big loss of performance. Do you really
think every character and integer should be an object?
Expressions, flowcontrol and arrays is mostly the same in object oriented
and procedural laguages, just about everything else is different.
I believe it's very helpful to learn to walk before trying to run. Is
a Formula 1 racecar really the best vehicle for beginning drivers? Or
are they actually more likely to get hurt?
All the "object oriented cruft" (he he) is only that if your only goal
is efficiency in executables, and "real" programming is assembly.
>
While anything is doable in assembly, it's obviously not a good
language to develop in because the code is difficult to modify and
nonportable; besides, writing better assembly than a good compiler can
generate is hard.

But all that is besides the point. We're talking about languages
suitable for *learning* programming, not for developing large applications.


Michal
 

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

No members online now.

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top