473,322 Members | 1,690 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Exercise 7-1

mdh
I am not sure how relevant to C this is, but here goes.
The exercise is to write a simple program "upper" that is invoked by
this name. The program itself is pretty easy...even for me. :-)
>>>>>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main (int argc, const char * argv[]) {
int c;
if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/
upper")==0)
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
else
putchar(tolower(c));
return 0;
}

<<<<<<

But, my question is this?
When I type "/.....upper" immediately followed by an argument, the
program does not work.
If I type "/...upper" RETURN, then enter the arguments, it works.
Any reason? I have asked on Xcode forum, but no answer yet?
If this is OT, then I apologize.
Sep 3 '08 #1
15 1812
mdh <md**@comcast.netwrites:
I am not sure how relevant to C this is, but here goes.
The exercise is to write a simple program "upper" that is invoked by
this name. The program itself is pretty easy...even for me. :-)
>>>>>>

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

int main (int argc, const char * argv[]) {
int c;
if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/
upper")==0)
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
else
putchar(tolower(c));
return 0;
}

<<<<<<

But, my question is this?
When I type "/.....upper" immediately followed by an argument, the
program does not work.
If I type "/...upper" RETURN, then enter the arguments, it works.
Any reason? I have asked on Xcode forum, but no answer yet?
If this is OT, then I apologize.
Having the program silently do nothing if argv[0] doesn't have a
specific value is odd, but if that's what you want it to do, that's
ok.

Your indentation is inconsistent and doesn't correspond either to the
actual structure of your code or to the intended structure of your
code.

Here's your program after it's been filtered through "indent -kr" (and
after I manually joined the split line):

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

int main(int argc, const char *argv[])
{
int c;
if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/upper") == 0)
while ((c = getchar()) != EOF)
putchar(toupper(c));
else
putchar(tolower(c));
return 0;
}

This should be enough to tell you what the problem is. It's also a
good argument for using braces for all structured statements, whether
they're required or not. For example, I always write:

if (condition) {
statement;
}

rather than

if (condition)
statement;

It makes this kind of error slightly more difficult to make.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 3 '08 #2
mdh
On Sep 2, 8:53*pm, Keith Thompson <ks...@mib.orgwrote:
mdh <m...@comcast.netwrites:
I am not sure how relevant to C this is, but here goes.
.

Your indentation is inconsistent and doesn't correspond either to the
actual structure of your code or to the intended structure of your
code.
Sorry about the formatting.I will have to figure that out sometime.
>
Here's your program after it's been filtered through "indent -kr" (and
after I manually joined the split line):

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

int main(int argc, const char *argv[])
{
* * int c;
* * if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/upper")== 0)
* * * * while ((c = getchar()) != EOF)
* * * * * * putchar(toupper(c));
* * else
* * * * putchar(tolower(c));
* * return 0;

}

This should be enough to tell you what the problem is.
The solution, except for the omission in error of a second "while ((c
= getchar()) != EOF)" is from Tondo and Gimpel. I think it is really
simple to illustrate the issue that K&R are trying to make, instead of
making it bullet proof?

>>>>>
while ((c = getchar()) != EOF){
putchar(toupper(c));
}
else {
while ((c = getchar()) != EOF)
putchar(tolower(c)); }

<<<<<

But, have I missed something. Is that the reason one needs a 2 step
invocation of this program?

Sep 3 '08 #3
On Sep 3, 6:34 am, mdh <m...@comcast.netwrote:
I am not sure how relevant to C this is, but here goes.
It's a C exercise from a C book, how more relevant can it be?
The exercise is to write a simple program "upper" that is invoked by
this name. The program itself is pretty easy...even for me. :-)
You seem to be having problems with it though...
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main (int argc, const char * argv[]) {
argv is char *argv[] or char **argv, etc.
Drop `const'.
int c;
if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/
upper")==0)
argv[argc] is always NULL. argc may be 0.
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
else
putchar(tolower(c));
`else' is reached if strcmp returns a non-zero value.
`c' is not initialized, thus you are invoking undefined behavior when
you use its value.
return 0;

}

<<<<<<

But, my question is this?
When I type "/.....upper" immediately followed by an argument, the
program does not work.
Because there are several errors in your code.
If I type "/...upper" RETURN, then enter the arguments, it works.
Any reason? I have asked on Xcode forum, but no answer yet?
If this is OT, then I apologize.
Because you read from stdin, you don't do anything with the arguments.
Here's a complete program that does what you want.

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

int main(void) {
int (*f[2])(int) = { toupper, tolower }, c, i;

if(argc == 0) return EXIT_FAILURE;
i = !!strcmp(argv[0], "upper");
while((c = getchar()) != EOF) putchar(f[i](c));
if(ferror(stdin)) return EXIT_FAILURE;
return 0;
}
Sep 3 '08 #4
On Sep 3, 8:48 am, vipps...@gmail.com wrote:

<snip>
int main(void) {
That should've been int argc, char **argv, heh.
Sep 3 '08 #5
mdh <md**@comcast.netwrites:
On Sep 2, 8:53*pm, Keith Thompson <ks...@mib.orgwrote:
>mdh <m...@comcast.netwrites:
I am not sure how relevant to C this is, but here goes.
.

Your indentation is inconsistent and doesn't correspond either to the
actual structure of your code or to the intended structure of your
code.

Sorry about the formatting.I will have to figure that out sometime.
>>
Here's your program after it's been filtered through "indent -kr" (and
after I manually joined the split line):

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

int main(int argc, const char *argv[])
{
* * int c;
* * if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/upper") == 0)
* * * * while ((c = getchar()) != EOF)
* * * * * * putchar(toupper(c));
* * else
* * * * putchar(tolower(c));
* * return 0;

}

This should be enough to tell you what the problem is.

The solution, except for the omission in error of a second "while ((c
= getchar()) != EOF)" is from Tondo and Gimpel.
That would be "The C Answer Book". If you're going to cite books
other than K&R, please be specific; I had to look that up.
I think it is really
simple to illustrate the issue that K&R are trying to make, instead of
making it bullet proof?

>>>>>>

while ((c = getchar()) != EOF){
putchar(toupper(c));
}
else {
while ((c = getchar()) != EOF)
putchar(tolower(c)); }

<<<<<

But, have I missed something. Is that the reason one needs a 2 step
invocation of this program?
(Does the subject "Exercise 7-1" refer to K&R? My copy isn't handy.)

I'm afraid I can't tell from your response whether you understood my
point or not. In the code you've marked with ">>>>>" and "<<<<<", you
have an "else" with no corresponding "if". If that's a fragment of
Tondo and Gimpel's solution, it's a poorly chosen fragment.

If I understand correct, the program is supposed to convert its input
to upper case if it's invoked as "upper", and to lower case otherwise.

The problem is that, due to the way you've structured the code, if
it's invoked as "upper" (or rather as "/Users/.../upper") it uses a
while loop to read each character from stdin, otherwise it reads only
a single character.

There are two obvious ways to do what you're trying to do.

In pseudo-code, with structure shown only by indentation, you can do
either:

if my name is "upper"
for each input character
print that character in upper case
else
for each input character
print that character in lower case

or:

for each input character
if my name is "upper"
print that character in upper case
else
print that character in lower case

What you've done is an incorrect mixture of the two approaches.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 3 '08 #6
On Wed, 03 Sep 2008 00:35:23 -0700, Keith Thompson posted:
>The solution, except for the omission in error of a second "while ((c
= getchar()) != EOF)" is from Tondo and Gimpel.

That would be "The C Answer Book". If you're going to cite books
other than K&R, please be specific; I had to look that up.
I've got Tondo and Gimpel at hand. I can't imagine that it would trump
Keith if the exercise were "do io in contemporary standard C."

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

#define MAXLINE 100
#define OCTLEN 6

int main ( int vipp, ** char star)
{
// berkeley bracing ala dan pop
int c, pos;
int inc(int pos, int n);

//main control
pos = 0;
while((c = getchar()) != EOF)
if (iscntrl(c) || c==' '
{
// non-graphic or blank
pos = inc(pos, OCTLEN);
printf =(" \\%03o ", c);
// sic

// newline ?
if (c == '\n')
{

pos = 0;
putchar('\n');

}

}
// brace mismatch alert

else
{

pos = inc( pos, 1);
putchar(c);

}
return 0;

// an external function; this belongs up top

int inc(int pos, int n)
{
if (pos + n < MAXLINE)
return pos + n;
else
{
putchar('\n');
return n;
}
}
Anyways, I like to type in the middle of the night. This is a classic

and outdated soultion. The T&C solns don't hold up together, with this

an example of monstrous msicalculation.

I don't have a C compiler online other than Richard right now.

}
--
When a new source of taxation is found it never means, in practice, that
the old source is abandoned. It merely means that the politicians have two
ways of milking the taxpayer where they had one before. 8
H. L. Mencken
Sep 3 '08 #7
mdh
On Sep 3, 12:35*am, Keith Thompson <ks...@mib.orgwrote:
mdh <m...@comcast.netwrites:
.
The solution, except for the omission in error of a second "while ((c
= getchar()) != EOF)" is from Tondo and Gimpel.

That would be "The C Answer Book". *If you're going to cite books
other than K&R, please be specific; I had to look that up.

Sorry about that. I assumed that Tondo and Gimpel and K&R were like a
"horse and carriage" and that everyone just knew about them.(Their
book is promoed on the back cover of my K&R) I have previously
alluded to them using the acronym "T&G" and it had not been
questioned...just goes to show where assumptions will get you! It
really has helped me up to now getting through those exercises.

>

(Does the subject "Exercise 7-1" refer to K&R? *My copy isn't handy.)
Yes it does..

"Write a program that converts upper case to lower case or lower case
to upper, depending upon the name that it is invoked with, as found in
argv[0]."
>
I'm afraid I can't tell from your response whether you understood my
point or not. *In the code you've marked with ">>>>>" and "<<<<<", you
have an "else" with no corresponding "if". *If that's a fragment of
Tondo and Gimpel's solution, it's a poorly chosen fragment.
It's a poorly chosen fragment.
My question was specifically directed to the problem of needing to
invoke the program ....which in my case means typing the path name and
then RETURN...then typing something in lower case, then RETURN
converts this to upper case.
As I thought the issue was not really related to the code that was
written, I did not really give due diligence to the issues you were
pointing out...which was my mistake, and which I will try and correct
below.

>
The problem is that, due to the way you've structured the code, if
it's invoked as "upper" (or rather as "/Users/.../upper") it uses a
while loop to read each character from stdin, otherwise it reads only
a single character.

There are two obvious ways to do what you're trying to do.

What you've done is an incorrect mixture of the two approaches.

Your point is taken. Let me then accept your code, but having done
this, does it answer the query that I am puzzled about?
And for completeness, I include, the **hopefully** full code from T&G
as well. ( I have added braces as per your suggestion )
>>>>>>>>>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main (int argc, char * argv[]) {
int c;
if (strcmp(argv[0], "upper")==0){
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
}
else {
while (( c = getchar() ) != EOF)
putchar(tolower(c));
}
return 0;
}

<<<<<<<<
Sep 3 '08 #8
mdh
On Sep 2, 10:48*pm, vipps...@gmail.com wrote:
On Sep 3, 6:34 am, mdh <m...@comcast.netwrote:
I am not sure how relevant to C this is, but here goes.

It's a C exercise from a C book, how more relevant can it be?
Well, I am not sure if it is a "C" issue or an "Xcode" issue, which is
what I use when working through the exercises. If it is an Xcode
issue, I think I would be directed to the appropriate forum ( which
exists) but having said that, I ask here to find out with certainty
which it is.
Sep 3 '08 #9
mdh <md**@comcast.netwrites:
[big snip]
Your point is taken. Let me then accept your code, but having done
this, does it answer the query that I am puzzled about?
And for completeness, I include, the **hopefully** full code from T&G
as well. ( I have added braces as per your suggestion )
>>>>>>>>>>

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

int main (int argc, char * argv[]) {
int c;
if (strcmp(argv[0], "upper")==0){
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
}
else {
while (( c = getchar() ) != EOF)
putchar(tolower(c));
}
return 0;
}

<<<<<<<<
Ok, that looks reasonable, mostly. Your indentation is still
inconsistent, and I'd add braces to the while statements as well as the
if statements:

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

int main(int argc, char *argv[])
{
int c;
if (strcmp(argv[0], "upper") == 0) {
while ((c = getchar()) != EOF) {
putchar(toupper(c));
}
}
else {
while ((c = getchar()) != EOF) {
putchar(tolower(c));
}
}
return 0;
}

But now I've lost track of what you were asking about.

One possible issue I can see is that argv[0], if it's non-null, points
to a string that "represents the program name". The manner in which
it does so may vary. For example, on a Unix-like system, it could be
any of "./upper", "/some/long/path/upper", or just "upper", depending
on how you invoked the program. I suggest printing the value of
argv[0] to see how it's actually being set. <OT>Try both installing
the program in some directory in your $PATH and invoking it by name,
and typing the full path to the executable file, and see what
happens.</OT>

For a simple test, you can just pick a way to invoke the program and
check for whatever value of argv[0] that gives you. For more
generality, you could figure out how to detect all the possible ways
it could be invoked.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 4 '08 #10
mdh
On Sep 3, 5:00*pm, Keith Thompson <ks...@mib.orgwrote:
mdh <m...@comcast.netwrites:

Ok, that looks reasonable, mostly.
Finally!! :-)
>
But now I've lost track of what you were asking about.

LOL!

The question was why one invoked the program by using the "name" , in
this case lower/upper. Then on my computer, I need to hit "Return",
then type some stuff, which, after a return, converts it to upper or
lower as requested in the name.

In other words, you cannot do this...

/....whateverthepathis/lower CONVERT ME TO LOWER

but you can do this.

/....whateverthepathis/lower RETURN

**program launches**

Now type:

CONVERT ME TO LOWER

and it performs as expected. ie output is "convert me to lower"
>
*I suggest printing the value of
argv[0] to see how it's actually being set.

Thank you...did not think of that.
Sep 4 '08 #11
On Sep 4, 2:40 am, mdh <m...@comcast.netwrote:
On Sep 2, 10:48 pm, vipps...@gmail.com wrote:
On Sep 3, 6:34 am, mdh <m...@comcast.netwrote:
I am not sure how relevant to C this is, but here goes.
It's a C exercise from a C book, how more relevant can it be?

Well, I am not sure if it is a "C" issue or an "Xcode" issue, which is
what I use when working through the exercises. If it is an Xcode
issue, I think I would be directed to the appropriate forum ( which
exists) but having said that, I ask here to find out with certainty
which it is.

It's a C exercise from a C book, how more relevant can it be?
Sep 4 '08 #12
On Tue, 2 Sep 2008 20:34:36 -0700 (PDT), mdh <md**@comcast.netwrote:
>I am not sure how relevant to C this is, but here goes.
The exercise is to write a simple program "upper" that is invoked by
this name. The program itself is pretty easy...even for me. :-)
>>>>>>

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

int main (int argc, const char * argv[]) {
int c;
if (strcmp(argv[0], "/Users/m/Desktop/upper/build/Release/
upper")==0)
while ( (c = getchar() ) != EOF)
putchar(toupper(c));
else
putchar(tolower(c));
return 0;
}

<<<<<<

But, my question is this?
When I type "/.....upper" immediately followed by an argument, the
program does not work.
If I type "/...upper" RETURN, then enter the arguments, it works.
Any reason? I have asked on Xcode forum, but no answer yet?
If this is OT, then I apologize.
After you fix the bad logic and undefined behavior in your code, print
out the string argv[0] points to and find out what your "shell" is
doing different between the two invocations of your program.

--
Remove del for email
Sep 4 '08 #13
mdh
On Sep 3, 9:12*pm, Barry Schwarz <schwa...@dqel.comwrote:
On Tue, 2 Sep 2008 20:34:36 -0700 (PDT), mdh <m...@comcast.netwrote:
..
>
After you fix the bad logic and undefined behavior in your code, print
out the string argv[0] points to and find out what your "shell" is
doing different between the two invocations of your program.
No difference.
As this is the first time K&R involved I/O use, I wanted to get this
working. What I missed was the fact that getchar() reads from the
standard input, as Keith showed with his diagram.

Sep 4 '08 #14
vi******@gmail.com wrote:
>
It's a C exercise from a C book, how more relevant can it be?
It's hard to say -- some books which claim to be about C contain
exercises that have little to nothing to do with C.
--
Larry Jones

Temporary insanity! That's all it was! -- Calvin
Sep 4 '08 #15
la************@siemens.com wrote:
vi******@gmail.com wrote:

It's a C exercise from a C book, how more relevant can it be?

It's hard to say -- some books which claim to be about C contain
exercises that have little to nothing to do with C.
Well, yeah, but in this case it's not from a C book, but from the C
book: K&R 2.

Richard
Sep 5 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Charles | last post by:
I am going through the exercises and Bruce Eckel's Thinking in C++ and I ran into an exercise that wasn't included in his solutions that I think I could use some assistance with. Exercise 3-26...
12
by: Merrill & Michele | last post by:
It's very difficult to do an exercise with elementary tools. It took me about fifteen minutes to get exercise 1-7: #include <stdio.h> int main(int orange, char **apple) { int c; c=-5;...
6
by: sathyashrayan | last post by:
Dear group, Following is a exercise from a book called "Oreilly's practical C programming". I just wanted to do a couple of C programming exercise. I do have K and R book, but let me try some...
8
by: Mike S | last post by:
Hi all, I noticed a very slight logic error in the solution to K&R Exercise 1-22 on the the CLC-Wiki, located at http://www.clc-wiki.net/wiki/KR2_Exercise_1-22 The exercise reads as...
16
by: Josh Zenker | last post by:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to me. Is there a more elegant way to do this? #include <stdio.h> /* copies input to output, printing */ /* series of...
5
by: ebrimagillen | last post by:
Hello mates, Just needed a solution on the exercises below. Exercise 2 A classic problem in introductory programming is the grains of rice on a chess board problem. Your program should...
5
by: Richard Gromstein | last post by:
Hello, I have an exercise that I need to finish very soon and I really need help understanding what to do and how exactly to do it. I am working on reading the chapter right now and working on it...
26
by: arnuld | last post by:
this is the programme i created, for exercise 2, assignment 3 at http://www.eskimo.com/~scs/cclass/asgn.beg/PS2.html it runs fine. i wanted to know if it needs any improvement: ...
19
by: arnuld | last post by:
this programme runs without any error but it does not do what i want it to do: ------------- PROGRAMME -------------- /* K&R2, section 1.6 Arrays; Exercise 1-13. STATEMENT: Write a program...
5
by: arnuld | last post by:
this is a programme that counts the "lengths" of each word and then prints that many of stars(*) on the output . it is a modified form of K&R2 exercise 1-13. the programme runs without any...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.