Program not giving any output

Discussion in 'C Programming' started by Maxx, Nov 7, 2010.

  1. Maxx

    Maxx Guest

    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.
     
    Maxx, Nov 7, 2010
    #1
    1. Advertising

  2. Maxx <> writes:

    > 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.

    > {
    > 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.


    --
    Ben.
     
    Ben Bacarisse, Nov 7, 2010
    #2
    1. Advertising

  3. Maxx

    Eric Sosman Guest

    On 11/7/2010 8:02 AM, Maxx wrote:
    > 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.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 7, 2010
    #3
  4. On Sun, 07 Nov 2010 08:02:02 -0500, Maxx <> wrote:
    ....
    > 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?
    --
    Morris Keesan --
     
    Morris Keesan, Nov 7, 2010
    #4
  5. Maxx

    Chad Guest

    On Nov 7, 6:32 am, Eric Sosman <> wrote:

    >      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]$
     
    Chad, Nov 7, 2010
    #5
  6. Chad <> writes:
    <snip>
    > #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>
    --
    Ben.
     
    Ben Bacarisse, Nov 7, 2010
    #6
  7. Maxx

    Eric Sosman Guest

    On 11/7/2010 2:00 PM, Chad wrote:
    >
    > 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.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 7, 2010
    #7
  8. Maxx

    Chad Guest

    On Nov 7, 12:26 pm, Ben Bacarisse <> wrote:

    > 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?
    >


    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.
     
    Chad, Nov 7, 2010
    #8
  9. Maxx

    Eric Sosman Guest

    On 11/7/2010 4:53 PM, Chad wrote:
    > On Nov 7, 12:26 pm, Ben Bacarisse<> wrote:
    >
    >> 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?
    >>

    >
    > 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.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 7, 2010
    #9
  10. Maxx

    Chad Guest

    On Nov 7, 2:55 pm, Eric Sosman <> wrote:
    >      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
     
    Chad, Nov 7, 2010
    #10
  11. Maxx

    Seebs Guest

    On 2010-11-07, Chad <> wrote:
    > 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
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
     
    Seebs, Nov 7, 2010
    #11
  12. Chad <> writes:
    > On Nov 7, 2:55 pm, Eric Sosman <> wrote:
    >>      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.


    Right, some posters don't consider every case.

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

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Nov 8, 2010
    #12
  13. Maxx

    Chad Guest

    On Nov 7, 3:54 pm, Seebs <> wrote:
    > On 2010-11-07, Chad <> wrote:
    >
    > > 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.
    >


    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);
    }
     
    Chad, Nov 8, 2010
    #13
  14. Chad <> wrote:
    > 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;
    }

    --
    Peter
     
    Peter Nilsson, Nov 8, 2010
    #14
  15. Maxx

    Eric Sosman Guest

    On 11/7/2010 8:35 PM, Chad wrote:
    > On Nov 7, 3:54 pm, Seebs<> wrote:
    >> On 2010-11-07, Chad<> wrote:
    >>
    >>> 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.
    >>

    >
    > 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?

    > }


    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 8, 2010
    #15
  16. Maxx

    Chad Guest

    On Nov 7, 5:59 pm, Peter Nilsson <> wrote:
    > Chad <> wrote:
    > > 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;
    >   }
    >


    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.
     
    Chad, Nov 8, 2010
    #16
  17. Maxx

    Eric Sosman Guest

    On 11/7/2010 8:59 PM, Peter Nilsson wrote:
    > Chad<> wrote:
    >> 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;


    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.

    > return 0;
    > }


    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 8, 2010
    #17
  18. Chad <> writes:
    <snip>
    > 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.

    --
    Ben.
     
    Ben Bacarisse, Nov 8, 2010
    #18
  19. Chad <> wrote:
    > Peter Nilsson <> wrote:
    > >   #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.


    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;
    }

    --
    Peter
     
    Peter Nilsson, Nov 8, 2010
    #19
  20. On Sun, 07 Nov 2010 17:55:55 -0500, Eric Sosman
    <> wrote:
    ....
    > 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'.

    --
    Morris Keesan --
     
    Morris Keesan, Nov 8, 2010
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. prasi

    why it is not giving any error?

    prasi, Oct 3, 2005, in forum: C Programming
    Replies:
    12
    Views:
    479
    Martin Ambuhl
    Oct 3, 2005
  2. prasi

    why it is not giving any error?

    prasi, Oct 3, 2005, in forum: C Programming
    Replies:
    3
    Views:
    291
    Keith Thompson
    Oct 4, 2005
  3. sixteenmillion

    The giving that keeps on giving

    sixteenmillion, Nov 19, 2007, in forum: C Programming
    Replies:
    0
    Views:
    455
    sixteenmillion
    Nov 19, 2007
  4. Maxx
    Replies:
    5
    Views:
    513
    BartC
    Feb 7, 2011
  5. Replies:
    9
    Views:
    77
    Rustom Mody
    Mar 22, 2014
Loading...

Share This Page