Program not giving any output

M

Maxx

Here i have a program which was supposed to do the following:

Example INPUT:::
Dolorian refused to release the
lyrics for the track 'A Part Of Darkness'
on 'When All The Laughter Has Gone',
and several parts of the lyrics on almost

Example OUTPUT:::::
Dolorian refused to release the
Lyrics for the track 'A Part Of Darkness'
On 'When All The Laughter Has Gone',
And several parts of the lyrics on almost

What this program does is basically checks the first letter of every
line and changes it to upper case.

Here is the program:::::


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define BUFFER 5000

int main(int argc, char **argv)
{
FILE *fp;
int a[BUFFER];
int ch,*p=a,*c=a;
if((fp=fopen(argv[1],"a")) == NULL)
{
fprintf(stderr,"%s can't open file %s",argv[0],argv[1]);
exit(1);
}
while((ch=getc(fp))!=EOF)
{
*p++=ch;
}*p='\0';
for(;*c!='\0';c++)
{
if(*c==10 || *c==13)
{
++c;
if(islower(*c))
{
*c=toupper(*c);
}
}
}
while(*c++!='\0')
{
putc(*c,fp);
}
fclose(fp);
return 0;
}

It's get compiled with zero error/warning but when i run it against
any file it produces no output or change.The input remains the
same.please help i'm having tough time solving it.
 
B

Ben Bacarisse

Maxx said:
Here i have a program which was supposed to do the following:

Example INPUT:::
Dolorian refused to release the
lyrics for the track 'A Part Of Darkness'
on 'When All The Laughter Has Gone',
and several parts of the lyrics on almost

Example OUTPUT:::::
Dolorian refused to release the
Lyrics for the track 'A Part Of Darkness'
On 'When All The Laughter Has Gone',
And several parts of the lyrics on almost

What this program does is basically checks the first letter of every
line and changes it to upper case.

Here is the program:::::


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define BUFFER 5000

There is no obvious need to store a large number of anything in this
program. It's a good exercise to re-think it so that the data you need
to store is unrelated to how long the input or input lines might be.
int main(int argc, char **argv)
{
FILE *fp;
int a[BUFFER];
int ch,*p=a,*c=a;

These are not very helpful names.
if((fp=fopen(argv[1],"a")) == NULL)

What do you think "a" does here? If you are not sure, look it up. I
could tell you, but you'll need to look up other stuff tomorrow, so find
some book or on-line reference now and be prepared.

But there are other points. What happens if argc is zero or one? Why
limit this program to files that can be named an opened? That might
have been part of the specification (it's not at all clear) but if not,
it would be better to make this program a filter: one that (at least
when no arguments are supplied) reads stdin and writes the modified data
to stdout.
{
fprintf(stderr,"%s can't open file %s",argv[0],argv[1]);
exit(1);
}
while((ch=getc(fp))!=EOF)
{
*p++=ch;

Add more white space to your code! What happens when 'p' runs off the
end of 'a'?
}*p='\0';
for(;*c!='\0';c++)

It's possible that 'c' can run past the end of you data. Can you work
out how that can happen?
{
if(*c==10 || *c==13)

(1) C makes sure that system dependent line terminations are converted
into the single '\n' character (for text streams). (2) Why write a
non-portable and mysterious number rather than '\n'?
{
++c;
if(islower(*c))
{
*c=toupper(*c);
}
}
}

Assuming that you don't run off the array, one thing you can be sure of
here is that *c is == 0 or the for loop would not have finished...
while(*c++!='\0')

so this loop won't do anything at all.
 
E

Eric Sosman

Here i have a program which was supposed to do the following:

Example INPUT:::
Dolorian refused to release the
lyrics for the track 'A Part Of Darkness'
on 'When All The Laughter Has Gone',
and several parts of the lyrics on almost

Example OUTPUT:::::
Dolorian refused to release the
Lyrics for the track 'A Part Of Darkness'
On 'When All The Laughter Has Gone',
And several parts of the lyrics on almost

What this program does is basically checks the first letter of every
line and changes it to upper case.

Here is the program:::::


#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define BUFFER 5000

int main(int argc, char **argv)
{
FILE *fp;
int a[BUFFER];
int ch,*p=a,*c=a;
if((fp=fopen(argv[1],"a")) == NULL)

Do you know what "a" means here? It means "open for appending."
You are opening a stream for *output* to the end of the file, not
for input of any kind. You probably mean "r+", which means "open
for reading and updating." A safer alternative might be to read
from one file and write another; "safer" because if your program
does something weird it won't have trashed the original input.

(Also, it would be a good idea to check that argv[1] is actually
present before trying to use it.)
{
fprintf(stderr,"%s can't open file %s",argv[0],argv[1]);
exit(1);
}
while((ch=getc(fp))!=EOF)
{
*p++=ch;
}*p='\0';
for(;*c!='\0';c++)
{
if(*c==10 || *c==13)

Side-note: You probably mean '\n' and '\r' instead of
those mysterious magic numbers. Furthermore, you don't need
to worry about the '\r' at all: C's text I/O streams always
use a single '\n' to mark the end of a line, regardless of
what's actually recorded in a file.
{
++c;
if(islower(*c))
{
*c=toupper(*c);
}
}
}

At this moment in your program, where does `c' point?
With that in mind, how many times will the body of the next
loop execute?
while(*c++!='\0')
{
putc(*c,fp);
}
fclose(fp);
return 0;
}

It's get compiled with zero error/warning but when i run it against
any file it produces no output or change.The input remains the
same.please help i'm having tough time solving it.

Side-note, this program is considerably more complicated (and
self-limited) than it needs to be to accomplish its stated task.
As you learn more, you'll see ways to simplify and improve it --
but right now, let's focus on the basics.
 
M

Morris Keesan

What this program does is basically checks the first letter of every
line and changes it to upper case. ....
if(*c==10 || *c==13)
{
++c;
if(islower(*c))
{
*c=toupper(*c);
}
}

Eric Sosman and and Ben Bacarisse have correctly diagnosed most of the
problems in your code, but there's another slightly subtle one.

What will your program do if the FIRST line of input begins with a
lower-case letter?
 
C

Chad

     Side-note, this program is considerably more complicated (and
self-limited) than it needs to be to accomplish its stated task.
As you learn more, you'll see ways to simplify and improve it --
but right now, let's focus on the basics.

I don't think this is what the op was looking for, but like, here is
what I came up with...

[cdalten@localhost oakland]$ more dol
Dolorian refused to release the
lyrics for the track 'A Part Of Darkness'
on 'When All The Laughter Has Gone',
and several parts of the lyrics on almost
[cdalten@localhost oakland]$
[cdalten@localhost oakland]$ more lotoup.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define PATH "/home/cdalten/oakland/dol"

int main(void)
{
FILE *fp;
char buf[BUFSIZ];

if ((fp = fopen(PATH, "r")) == NULL) {
fprintf(stderr, "Can't open input file\n");
exit(EXIT_FAILURE);
}

while (fgets(buf, BUFSIZ, fp) != NULL) {
printf("%c%s",toupper(buf[0]), &buf[1]);
}

printf("\n");

fclose(fp);
exit(EXIT_SUCCESS);
}
[cdalten@localhost oakland]$ gcc -Wall -Wextra lotoup.c -o lotoup
[cdalten@localhost oakland]$ ./lotoup
Dolorian refused to release the
Lyrics for the track 'A Part Of Darkness'
On 'When All The Laughter Has Gone',
And several parts of the lyrics on almost
[cdalten@localhost oakland]$
 
B

Ben Bacarisse

Chad said:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define PATH "/home/cdalten/oakland/dol"

int main(void)
{
FILE *fp;
char buf[BUFSIZ];

Why link the line length that you are prepared to accept with the size
of an internal IO buffer?
if ((fp = fopen(PATH, "r")) == NULL) {
fprintf(stderr, "Can't open input file\n");
exit(EXIT_FAILURE);
}

It seems a shame to insist that the data be in one named file. Even if
not required, isn't it easier to test if the program is more generous
about what it accepts?
while (fgets(buf, BUFSIZ, fp) != NULL) {
printf("%c%s",toupper(buf[0]), &buf[1]);
}

But here's the key thing: by insisting on reading a line at a time, you
complicate the program and introduce a limit at the same time. Can you
think of a way to avoid an line length limit? Does it simplify the
program?
printf("\n");

What's this for?
fclose(fp);
exit(EXIT_SUCCESS);
}

<snip>
 
E

Eric Sosman

I don't think this is what the op was looking for, but like, here is
what I came up with...

In addition to Ben's comments, allow me to point out this
all-too-common howler:
char buf[BUFSIZ];
[...]
printf("%c%s",toupper(buf[0]),&buf[1]);

Use `toupper( (unsigned char)buf[0] )' instead. I won't explain
why, because it's been explained over and over and over; peruse
the archives (or your C reference) for yourself.
 
C

Chad

But here's the key thing: by insisting on reading a line at a time, you
complicate the program and introduce a limit at the same time.  Can you
think of a way to avoid an line length limit?  Does it simplify the
program?


What's this for?

Here is how I avoided the line length limit...

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

int main(int argc, char **argv)
{
FILE *fp;
int c;

if (argc != 2) {
fprintf(stderr, "Enter a file name.\n");
exit(EXIT_FAILURE);
}

if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Can't open %s file.\n", argv[1]);
exit(EXIT_FAILURE);
}

while ((c = getc(fp)) != EOF) {
if ((fputc(c, stdout)) == EOF) {
fprintf(stderr, "Output error.\n");
exit(EXIT_FAILURE);
}
if (c == '\n') {
if ((c = getc(fp)) == EOF) {
fprintf(stderr, "getc error.\n");
exit(EXIT_FAILURE);
}

if ((fputc((unsigned char)toupper(c), stdout)) == EOF) {
fprintf(stderr, "Output error.\n");
exit(EXIT_FAILURE);
}
}
}

/*If there isn't a newline after the last character in the file*/
printf("\n");

fclose(fp);
exit(EXIT_SUCCESS);
}

I'm not too sure if this approach simplifies the program.
 
E

Eric Sosman

But here's the key thing: by insisting on reading a line at a time, you
complicate the program and introduce a limit at the same time. Can you
think of a way to avoid an line length limit? Does it simplify the
program?


What's this for?

Here is how I avoided the line length limit...

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

int main(int argc, char **argv)
{
FILE *fp;
int c;

if (argc != 2) {
fprintf(stderr, "Enter a file name.\n");
exit(EXIT_FAILURE);
}

if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Can't open %s file.\n", argv[1]);
exit(EXIT_FAILURE);
}

while ((c = getc(fp)) != EOF) {
if ((fputc(c, stdout)) == EOF) {
fprintf(stderr, "Output error.\n");
exit(EXIT_FAILURE);
}
if (c == '\n') {
if ((c = getc(fp)) == EOF) {
fprintf(stderr, "getc error.\n");
exit(EXIT_FAILURE);
}

if ((fputc((unsigned char)toupper(c), stdout)) == EOF) {
fprintf(stderr, "Output error.\n");
exit(EXIT_FAILURE);
}
}
}

/*If there isn't a newline after the last character in the file*/
printf("\n");

fclose(fp);
exit(EXIT_SUCCESS);
}

I'm not too sure if this approach simplifies the program.

Not much, but it introduces a new bug. And it's odd that
all the scrupulous error-checking of each fputc() (why not putc()
or putchar(), by the way?) is not matched by similar checking for
the printf() -- but then, the printf() seems to be extraneous
anyhow. And it's got a useless cast. And it's ugly.

If you haven't spotted the new bug yet, try this input:

oh what a tangled web we weave
when first we practice to write c!

that should be "ceave," but what the heck:
it wouldn't pass a spelling check.
 
C

Chad

     Not much, but it introduces a new bug.  And it's odd that
all the scrupulous error-checking of each fputc() (why not putc()
or putchar(), by the way?) is not matched by similar checking for
the printf() -- but then, the printf() seems to be extraneous
anyhow.  And it's got a useless cast.  And it's ugly.

     If you haven't spotted the new bug yet, try this input:

oh what a tangled web we weave
when first we practice to write c!

that should be "ceave," but what the heck:
it wouldn't pass a spelling check.

You do realize that this is probably a case that the OP isn't ready
for yet don't you? I hate to break it to you, but there are some
posters here that don't consider every case. This is because there are
some posters that are rookies when it comes to structured programming.
With that, I'm about a half second from entering you into my kill
file.

Chad
 
S

Seebs

You do realize that this is probably a case that the OP isn't ready
for yet don't you?

I am not sure I'm happy with the notion of teaching people to do stuff
wrong because they're "not ready" to do it right.
I hate to break it to you, but there are some
posters here that don't consider every case.

Yes.

And one of the benefits of this group is that more experienced programmers
can help them fix that.
This is because there are
some posters that are rookies when it comes to structured programming.

Best time to learn.

-s
 
K

Keith Thompson

Chad said:
You do realize that this is probably a case that the OP isn't ready
for yet don't you? I hate to break it to you, but there are some
posters here that don't consider every case. This is because there are
some posters that are rookies when it comes to structured programming.
With that, I'm about a half second from entering you into my kill
file.

Right, some posters don't consider every case.

Apparently you consider it rude to teach them to do so.
 
C

Chad

I am not sure I'm happy with the notion of teaching people to do stuff
wrong because they're "not ready" to do it right.


Yes.

And one of the benefits of this group is that more experienced programmers
can help them fix that.


Best time to learn.

Round 3. This code now works not only with the OPs original file, but
also, with Eric's input file...

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

int main(int argc, char **argv)
{
FILE *fp;
int c, prev;

if (argc != 2) {
fprintf(stderr, "Enter a file name.\n");
exit(EXIT_FAILURE);
}

if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Can't open %s file.\n", argv[1]);
exit(EXIT_FAILURE);
}

c = getc(fp);
printf("%c", toupper(c));

while ( ((c = getc(fp)) != EOF) ) {
prev = c;
printf("%c", c);

while (c == '\n') {
if ((c = getc(fp)) == EOF) {
break;
}
printf("%c", toupper(c));
}
}

if (prev != '\n')
printf("\n");

fclose(fp);
exit(EXIT_SUCCESS);
}
 
P

Peter Nilsson

Chad said:
Round 3. This code now works not only with the OPs original
file, but also, with Eric's input file... ....
  c = getc(fp);
  printf("%c", toupper(c));

But not with an empty file.

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

int main(void)
{
int ch, nl = 1;

while ((ch = getchar()) != EOF)
{
if (nl) { ch = toupper(ch); nl = 0; }
putchar(ch);
if (ch == '\n') nl = 1;
}

return 0;
}
 
E

Eric Sosman

Round 3. This code now works not only with the OPs original file, but
also, with Eric's input file...

Round 3 is your best yet, but the bug isn't quite dead: a
feeble feeler still flutters. And look! another bug has crawled
up to keep the first one company! Here are a few tests you
might want to make:

- Try an input file with an empty first line and a lower-
case letter at the start of the second.

- Try an input file with an embedded run of two or more
empty lines, followed by a line that starts with a lower-
case letter.

- Try a completely empty file, without even a lonesome '\n'.

- Try an input line with embedded empty lines, and compare
its line count with that of the program's output.

It seems to me you're sort of trying to subdue a complicated
problem by whacking it with great wads of complicated code. You've
gotten rid of some of the complexity, but there's still too much --
because the problem is *not* complicated, if you think about it the
right way. All you're trying to do is capitalize the first character
of each line and copy all the others, so the only thing you need to
know about each character as you handle it is "Are you the first of
a line?" If you think about what a "line" is, and consider the
conditions that distinguish a first-of-line character from a rest-
of-line character, I'm sure you'll arrive at a much simpler (and more
clearly correct) program.

A few other comments are in-line below.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

int main(int argc, char **argv)
{
FILE *fp;
int c, prev;

if (argc != 2) {
fprintf(stderr, "Enter a file name.\n");

fputs("Enter...", stderr) would also work, and might well be
FASTER OMIGOD SPEED YES GOTTA HAVE IT!
exit(EXIT_FAILURE);

Since this is main(), `return EXIT_FAILURE' would also work.
}

if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Can't open %s file.\n", argv[1]);
exit(EXIT_FAILURE);
}

c = getc(fp);
printf("%c", toupper(c));

Consider putchar(), instead of revving up all that printf()
machinery and laboriously interpreting a format string -- just
to arrive at a character code that's already in your grasp.
while ( ((c = getc(fp)) != EOF) ) {
prev = c;
printf("%c", c);
>
while (c == '\n') {
if ((c = getc(fp)) == EOF) {
break;

And what happens next, after breaking out of this loop?
}
printf("%c", toupper(c));
}
}

if (prev != '\n')
printf("\n");
fclose(fp);
exit(EXIT_SUCCESS);

Why "success," when all you know (sort of) is that getc()
stopped? You don't know whether you've read all the input, or
maybe had an I/O error. And what about output errors, hmmm?
 
C

Chad

But not with an empty file.

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

  int main(void)
  {
    int ch, nl = 1;

    while ((ch = getchar()) != EOF)
    {
      if (nl) { ch = toupper(ch); nl = 0; }
      putchar(ch);
      if (ch == '\n') nl = 1;
    }

    return 0;
  }

Using 'nl' as a test for true and false still eludes me. This, along
with a few other things, are probably the reasons why I don't work as
a computer programmer for a living.
 
E

Eric Sosman

But not with an empty file.

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

int main(void)
{
int ch, nl = 1;

while ((ch = getchar()) != EOF)
{
if (nl) { ch = toupper(ch); nl = 0; }
putchar(ch);
if (ch == '\n') nl = 1;

This would be a little sleeker, I think, as

putchar(nl ? toupper(ch) : ch);
nl = (ch == '\n');

.... but not everybody likes the conditional operator. (On a recent
code review, one of my reviewers protested three uses in two statements
and made me rewrite them as if's, even though this turned five or six
lines of code into about a dozen. Can't please everyone ...)

A few calls to fflush() and ferror() might be welcome here.
 
B

Ben Bacarisse

Chad said:
Round 3. This code now works not only with the OPs original file, but
also, with Eric's input file...

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

int main(int argc, char **argv)
{
FILE *fp;
int c, prev;

if (argc != 2) {
fprintf(stderr, "Enter a file name.\n");
exit(EXIT_FAILURE);
}

if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Can't open %s file.\n", argv[1]);
exit(EXIT_FAILURE);
}

c = getc(fp);
printf("%c", toupper(c));

while ( ((c = getc(fp)) != EOF) ) {
prev = c;
printf("%c", c);

while (c == '\n') {
if ((c = getc(fp)) == EOF) {
break;
}
printf("%c", toupper(c));
}
}

if (prev != '\n')
printf("\n");

fclose(fp);
exit(EXIT_SUCCESS);
}

You are adding bugs as fast as you remove them. For example, this
version goes wrong if there is no input at all or if the input consists
of a single character. This is often a sign that it's time to take a
step back and re-think.

Here's a tip... I've found that lots of beginners start by writing
programs by following the sequence of what should happen: "first do
this, and then do..." to which various conditions get added along
the way "except if this... but when that..." as it becomes clear that
the program does not quite do what is expected. But your first version
was better because it always did the same thing: every line gets read
and printed with the first letter capitalised. That's good and clear
but it imposes a needless limit on the program, and the array and the
fgets call make it mode fiddly than it needs to be.

The ideal solution here has the simplicity of your first version without
either of the drawbacks. Try to find a rule whereby you can treat every
character in the same way: for every character, print it plain or
capitalised if... what?

I fear that I've not explained this well and that you won't get what I
am driving at until you have exactly the solution that I have in mind
because, of course, you don't treat every character in the same way --
only some get capitalised -- but the point is to make the same
assessment of every character.
 
P

Peter Nilsson

Chad said:
Using 'nl' as a test for true and false still eludes me.

Then consider...

int ch;
int pch = '\n'; /* previous character */

while ((ch = getchar()) != EOF)
{
if (pch == '\n') /* start of a new line? */
ch = toupper(ch);
putchar(ch);
pch = ch;
}
 
M

Morris Keesan

On Sun, 07 Nov 2010 17:55:55 -0500, Eric Sosman
If you haven't spotted the new bug yet, try this input:

oh what a tangled web we weave
when first we practice to write c!
....

That's not a new bug. The OP's original code would have left the
initial 'o' as an 'o'.
 

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
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top