Pure C function pointer on printing vowels twice


 
Thread Tools Search this Thread
Top Forums Programming Pure C function pointer on printing vowels twice
# 1  
Old 05-17-2017
Pure C function pointer on printing vowels twice

Have difficulty to understand this pure C code to only print vowels twice from input string. Questions are commented at the end of each place.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
/*
 *Demonstrate the use of dispatch tables
 */

/*Print a char twice like putchar, return char if successful, or EOF on error.*/

int putcharTwice(int c)
{
    if (putchar(c) == EOF || putchar(c) == EOF)  {//Q1
    return EOF;
    } else {
    return c;
    }
}

#define NUM_CHARS (UCHAR_MAX + 1)    //UCHAR_MAX is in limits.h

int main(int argc, char **argv)
{
/*This declares table as array of function pointers */
    int (*table[NUM_CHARS]) (int);   //Q2
    int i;
    int c;

    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice; //Q3, and following 4 lines
    table['e'] = putcharTwice; //Q3
    table['i'] = putcharTwice; //Q3
    table['o'] = putcharTwice; //Q3
    table['u'] = putcharTwice; //Q3

    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }
    return 0;
}

The code was compiled without any problem,
Code:
$ echo "The quick brown fox jumps over the lazy dog!" | ./a.out
$ Thee quuiick broown foox juumps ooveer thee laazy doog!

Q1: How does the logic work by repeating the same condition on both sides of "||" ? I tried using only one side of the OR condition, the code compiled without error but did not work as expected.

Q2:Even not quite sure how to ask this question. Is this a prototype of a function? But the calling is without any parameter see Q3.

Q3: Calling of the function does not have a parameter at all. How does it work?

Q4: I thought I understand this line, but I must have wrong catch because of Q2.

Thanks a lot!
# 2  
Old 05-17-2017
Quote:
Originally Posted by yifangt
Have difficulty to understand this pure C code to only print vowels twice from input string. Questions are commented at the end of each place.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
/*
 *Demonstrate the use of dispatch tables
 */

/*Print a char twice like putchar, return char if successful, or EOF on error.*/

int putcharTwice(int c)
{
    if (putchar(c) == EOF || putchar(c) == EOF)  {//Q1
    return EOF;
    } else {
    return c;
    }
}

#define NUM_CHARS (UCHAR_MAX + 1)    //UCHAR_MAX is in limits.h

int main(int argc, char **argv)
{
/*This declares table as array of function pointers */
    int (*table[NUM_CHARS]) (int);   //Q2
    int i;
    int c;

    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice; //Q3, and following 4 lines
    table['e'] = putcharTwice; //Q3
    table['i'] = putcharTwice; //Q3
    table['o'] = putcharTwice; //Q3
    table['u'] = putcharTwice; //Q3

    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }
    return 0;
}

The code was compiled without any problem,
Code:
$ echo "The quick brown fox jumps over the lazy dog!" | ./a.out
$ Thee quuiick broown foox juumps ooveer thee laazy doog!

Q1: How does the logic work by repeating the same condition on both sides of "||" ? I tried using only one side of the OR condition, the code compiled without error but did not work as expected.
putchar(c) returns 0 on success or EOF on error. So, if the first putchar(c) succeeds, the second putchar(c) will also be executed. If both of them succeed, the expression tested will be 0 || 0 and the else side of the if statement will have putcharTwice() return c. If either putchar(c) failed, putcharTwice() will return EOF.

Quote:
Q2:Even not quite sure how to ask this question. Is this a prototype of a function? But the calling is without any parameter see Q3.
int (*table[NUM_CHARS]) (int); is a declaration stating that table is an array of 256 pointers to functions and those functions take one argument of type int and return an int.

Quote:
Q3: Calling of the function does not have a parameter at all. How does it work?
Code:
    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

sets the 1st 255 of the 256 elements of the table[] array to be a pointer to the putchar() function. It does not call putchar().

Code:
    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice;

resets the elements of the table[] array corresponding the the character a to point to the function putcharTwice(). And the following statements do the same thing for the other lowercase vowels in the English alphabet. These assignments do not call putchar() or putcharTwice() either.

Quote:
Q4: I thought I understand this line, but I must have wrong catch because of Q2.
Code:
    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }

is a loop that reads one character at a time from standard input until it detects an error or end-of-file condition. For each character read, it calls the function specified by the element of table[] corresponding to the character read with an argument that is the character read.

Quote:
Thanks a lot!
Hope this helps.
These 2 Users Gave Thanks to Don Cragun For This Post:
# 3  
Old 05-17-2017
Thanks Don! I seem to get closer to understand it. With a simpler test, here is my dissection of the execution:
Code:
 $ echo Test | ./a.out 
table['T'] ~~> putchar('T');  
table['e'] ~~> putcharTwice('e');  
table['s'] ~~> putchar('s');
table['t'] ~~> putchar('t');

but I still did not get how putcharTwice( int c) print the chars (now vowels only) twice.
For putcharTwice('e'): (putchar('e') == EOF || putchar('e') == EOF) becomes (0 || 0) so that the else block is executed to return 'e'; but how is 'e' printed twice to have ee with this function?

Thanks again!

Last edited by yifangt; 05-17-2017 at 01:45 PM.. Reason: typo
# 4  
Old 05-17-2017
Quote:
but I still did not get how putcharTwice( int c) print the chars (now vowels only) twice.
Because putchar isn't returning EOF.
From man putchar:
Code:
RETURN VALUE
       fputc(),  putc()  and  putchar()  return  the  character  written as an
       unsigned char cast to an int, or EOF on error.

So if you're printing C, it ends up testing 'C' == EOF, which evaluates to 0, allowing it to reach the second part, testing 'C' == EOF again, which is false again.
# 5  
Old 05-17-2017
Is there another layer hidden behind for printing with putchar() in the if-condition?

The return value is EOF or a single vowel, which is the first part bugging me.

Does that mean in if (putchar(c) == EOF || putchar(c) == EOF) , function putchar(c) gets actually executed twice?

I thought this line is just a condition, and before the end only the else block is executed so that the value is 'e', without printing.
Let me put my question in another way:
Is there another layer for printing hidden behind, such as when 'e' is encountered in 'Test'?
Code:
putchar(c);    //Is this the place 'e' get printed the first time?
left ~> (putchar(e) == EOF) is false, 0
putchar(c);    //Is this the place 'e' get printed the second time?
right ~> (putchar(e) == EOF is false, 0
so that, the if (0 || 0) condition still false; 
else block executed

Is this correct?
Thanks!

Last edited by yifangt; 05-17-2017 at 04:26 PM..
# 6  
Old 05-17-2017
Quote:
Originally Posted by yifangt
The return value is EOF or a single vowel, which is the first part bugging me.

Does that mean in if (putchar(c) == EOF || putchar(c) == EOF) , function putchar(c) gets actually executed twice?
Yes. To evaluate the expression, it has to call the function.

Quote:
I thought this line is just a condition
Slapping an if() around it doesn't change it. Would you expect this to print the values?

Code:
#include <stdio.h>

int main(void) {
    printf("a") && printf("b");
}

Treat anything inside an if() the exact same way.

Quote:
Let me put my question in another way:
Is there another layer
No.

For C, the answer to this question is always "no".

With very specific exceptions - like atexit() - C will never call a function without being asked.
# 7  
Old 05-17-2017
What I meant is: Does putchar(c) == EOF have two layers?
First,
putchar(c), which will print 'c' out;
Second, evaluate putchar(c) == EOF, which is false because first step is successful.
How does 'e' get printed twice in 'Test'? I need each step through the code.
i.e. how the function putcharTwice(int c) print each 'c' twice?

Thanks!

Last edited by yifangt; 05-17-2017 at 05:08 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

Segmentation fault when I pass a char pointer to a function in C.

I am passing a char* to the function "reverse" and when I execute it with gdb I get: Program received signal SIGSEGV, Segmentation fault. 0x000000000040083b in reverse (s=0x400b2b "hello") at pointersExample.c:72 72 *q = *p; Attached is the source code. I do not understand why... (9 Replies)
Discussion started by: jose_spain
9 Replies

2. UNIX for Dummies Questions & Answers

Counting vowels in string. "Comparison pointer-integer".

I'm trying to write a programme which scans strings to find how many vowels they contain. I get an error saying that I'm trying to compare a pointer and an integer inif(*v == scanme){. How can I overcome this ? Also, the programme seems to scan only the first word of a string e.g.: if I type "abc... (1 Reply)
Discussion started by: fakuse
1 Replies

3. Programming

Trivial doubt about C function pointer

Hi, In the below C code, #include <stdio.h> void print() { printf("Hello\n"); } int main() { void (*f)() = (void (*)()) print; f(); (*f)(); } I wonder, how the syntaxes "f()" and "(*f)()" are treated as same without any error? Is this an improvement or ANSI/ISO... (1 Reply)
Discussion started by: royalibrahim
1 Replies

4. Programming

structure pointer array as function parameters

if i create an array of pointers to a structure "struct node" as: struct node *r; and create "n" number of "linked lists" and assign it to the various struct pointers r using some function with a return type as structure pointer as: r=multiplty(.......) /*some parameters*/ is... (2 Replies)
Discussion started by: mscoder
2 Replies

5. UNIX for Dummies Questions & Answers

Printing pointer address

How can I print the memory address of a pointer using printf (or any other STDOUT functions?). I see in Linux its %p but not in unix, help? thanks (5 Replies)
Discussion started by: perleo
5 Replies

6. Programming

Function Returning Pointer

Hi guys. how a functions such fdopen, ... can return pointer? are these functions use static memory(variables)? (6 Replies)
Discussion started by: majid.merkava
6 Replies

7. Programming

Function pointer to inline function ?

Hi. Problem: I have to parse the payload of a packet. The payload could be in Big Endian Format (network byte order) or little. That depends on a flag present in the header of the packet. Solution: A horrible solution could be to check for that flag everytime I have to read a field in the... (11 Replies)
Discussion started by: emitrax
11 Replies

8. Programming

How to return void function pointer

Hello all im trying to build function that will return void function pointer what is mean is ( not working ) the main function void * myClass::getFunction(int type){ if(type==1) return &myClass::Test1; if(type==2) return &myClass::Test2; } void myClass::Test1(){... (1 Reply)
Discussion started by: umen
1 Replies

9. Programming

Pure Virtual Function in C++

Dear All, Here I want to know why we put =0 in case of pure virtual function, why not =1, =2 or any thing else Please send me answer any one as soon as possible. (1 Reply)
Discussion started by: krishna_sicsr
1 Replies

10. Programming

Problem with function which reutrns pointer to a value

i have a function: char *pcCityIdToCountryName(ADMIN_DB_DATA *pstHEader, unit uiCityID) this returns a pointer to CountryName if cityId is given. to retrieve countryname i give: char *CountryName; CountryName = pcCityIdToCountryName(..................); but when i compile it is giving :... (5 Replies)
Discussion started by: jazz
5 Replies
Login or Register to Ask a Question