Question

I have written the following program to answer Kernighan and Ritchies ch1 problem 12.

The issue is that I have never really understood how to properly use functions and would like to know why the one I wrote into this program, getcharc(), does not work?

What are good resources that explain correct function usage. Where? and How?

I know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:

#include <stdio.h>
int getcharc ();
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        while ( c == '\t') {
            getcharc(c);
        }
        while ( c == '\b') {
            getcharc(c);
        }
        while ( c == '\\') {
            getcharc(c);
        }
        while ( c == ' ') {
            getcharc(c);
        }
        putchar(c);
    }
}
int getcharc ()
{
    int c;

    c = getchar();
    printf("\n");
    return 0;
}

The original program (and I know it has bugs), without the function was:

#include <stdio.h>

// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        while ( c == '\t') {
            c = getchar();
            printf("\n");
        }
        while ( c == '\b') {
            c = getchar();
            printf("\n");
        }
        while ( c == '\\') {
            c = getchar();
            printf("\n");
        }
        while ( c == ' ') {
            c = getchar();
            printf("\n");
        }
        putchar(c);
    }
}

So all I am trying to do with the function is to stop

c = getchar();
printf("\n");

being repeated every time.

Was it helpful?

Solution 2

One of the possible solution is, change prototype for your function to int getcharc (int c, int flag).
Now your code after some modification;

#include <stdio.h>
int getcharc (int c, int flag);
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;
    int flag = 0;  //to keep track of repeated newline chars.

    while ((c = getchar()) != '\n') {
        flag = getcharc(c, flag);   // call getcharc() for each char in the input string. Testing for newline and printing of chars be done in the getcharc() function
    }
    return 0;     
}

int getcharc (int c, int flag)
{
        if( (c == ' ' || c == '\t' || c == '\b' || c== '\\')  && flag == 0)
        {
            printf("\n");
            flag = 1;
        }
        else
        {
            if(c != ' ' && c != '\t' && c != '\b' && c!= '\\')
                {
                     putchar(c);
                     flag = 0;
                }
        }
        return flag;
}

EDIT:

but I wanted to keep the nested while statements rather than using || or

Your nested while loop is executing only once for each character as grtchar() reads one character at one time. No need of nested loops here! You can check it by replacing while to if and your code will give the same output for a given string. See the output here.

know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:

You make your program work to some extent (with your bugs) by adding an if condition and a break statement as;

#include <stdio.h>
int getcharc (int c);

int main()
{
    int c;

    while ((c = getchar()) != '\n') {
        while ( c == '\t') {
            c = getcharc(c);
            if(c != '\t')
                break;
            }

        ....
        ....


        while ( c == ' ') {
            c = getcharc(c);
            if(c != ' ')
                break;
            }
        putchar(c);
    }
    return 0;
}
int getcharc (int c)
{
    c = getchar();
    printf("\n");
    return c;
}

OTHER TIPS

What, exactly, is this getcharc() function supposed to do? What it does, is read a character from input, print a newline, and return zero. The character just read from input is discarded, because you didn't do anything with it. When it's called, the return value is ignored as well. In each of the places where it is called, you're calling it in an infinite loop, because there's no provision made for changing the loop control variable.

Perhaps you were intending something like c = getcharc(), but that wouldn't really help because you aren't returning c from the function, anyway. (Well, it would help with the "infinite loop" part, anyway.)

What's the point of this function anyway? If you just use getchar() correctly in its place, it looks like you'd have your solution, barring a few other bugs.

// compiled by my brain muhahaha

#include <stdio.h>
int getcharc(); // we prototype getcharc without an argument

int main()
{
    int c; // we declare c

    // read character from stdio, if end of file quit, store read character in c
    while ((c = getchar()) != EOF) {  
        // if c is tab \t call function getcharc() until forever since c never changes
        while ( c == '\t') { 
            getcharc(c); // we call function getcharc with an argument
            // however getcharc doesn't take an argument according to the prototype
        }
        // if c is \b call function getcharc() until forever since c never changes
        while ( c == '\b') {
            getcharc(c);
        }
        // if c is \\ call function getcharc() until forever since c never changes
        while ( c == '\\') {
            getcharc(c);
        }
        // if c is ' ' call function getcharc() until forever since c never changes
        while ( c == ' ') {
            getcharc(c);
        }
        // since we never will get here but if we happened to get here by some
        // strange influence of some rare cosmic phenomena print out c
        putchar(c);
    }
}

// getcharc doesn't take an argument
int getcharc ()
{
    int c;  // we declare another c

    c = getchar(); // we read from the keyboard a character
    printf("\n"); // we print a newline
    return 0; // we return 0 which anyway will never be read by anyone
}

maybe you are getting confused with the old K&R

nowadays when you write a function argument you specify it like

int getcharch(int c)
{
  ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top