0

I have a problem where I have to print a string read from the console after the following rule: After two successive vowels or consonants I need to print the character _ but not if there are two vowels or two consonants at the end of the string, then I have to print the number of the substrings separated by each _ character. The string is read until EOF.

I have run into two problems:

  • The program will not terminate unless I type EOF (Ctrl-Z) on a new line. If I just add it at the end of the string, it will continue.

  • I need a way to check if the last character printed is '_', and to remove it if it is at the end of the printed string.

Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
    char vow[]="aeiouAEIOU", c,x;
    int nr=1;
    x=getchar();
    putchar(x);
    while((c=getchar())!=EOF)
    {
        if(isalpha(c))
        {
            if (((strchr(vow,x)&&strchr(vow,c))||(!strchr(vow,x)&&!strchr(vow,c)))&&x!=0)
            {
                putchar(c);
                putchar('_');
                nr++;
                x=0;
            }
            else
            {
                putchar(c);
                x=c;
            }
        }
    }
    printf("\n%d",--nr);
    return 0;
}
unwind
  • 391,730
  • 64
  • 469
  • 606
Stevie
  • 149
  • 6
  • 17
  • 2
    Can you provide an example input/output text of the desired result? – grek40 Jan 26 '17 at 11:50
  • The Ctrl-Z is addressed at : http://stackoverflow.com/questions/19372774/why-is-input-only-sometimes-terminated-when-i-press-ctrlz-in-a-windows-console – racraman Jan 26 '17 at 11:50
  • @grek40 IN:aaabceeeo OUT:aa_abc_ee_eo 4 – Stevie Jan 26 '17 at 11:53
  • Lets do some hostile reading. If the input is `aaa_b`, the output would be `aa_a_b ?` counting only the added separator `_` or also the `_` that was already part of the input? (or is the input guaranteed not to contain certain characters?) – grek40 Jan 26 '17 at 11:59
  • 3
    `while((c=getchar())!=EOF)` `c` should be an int, not a char. – joop Jan 26 '17 at 12:02
  • 1
    There is your code indeed. What's wrong with it? What is the question? – Lundin Jan 26 '17 at 12:04
  • @grek40 The program will only consider characters that are alphabetical. This is why I test each char if "isaplha(c)". so the input for aaa_b would be the same for the input aaab, as other chatacters than the alphabetical ones will be ignored, so the output is aa_ab 4 – Stevie Jan 26 '17 at 12:08
  • @Lundin The program will not terminate unless I type Ctrl+Z on a new line. If I just add it at the end of the input string, it will not terminate. And I need an idea: How can I check if the last character printed with putchar() is _ and how to remove it. For example: INPUT: aabb OUTPUT aa_bb_ . But I don't want that "_" at the end of the output string. – Stevie Jan 26 '17 at 12:12
  • @Stevie Okay, you should edit your post and add those details there. It makes the question much better as you turn it specific. – Lundin Jan 26 '17 at 12:19
  • 1
    As a side note, you are calling `strchr` more often than necessary. If you want to write an `a XOR b` in C, you can use `!a != !b` (`!strchr(vow,x) != !strchr(vow,c)`, additionally negate the result for your case, so its actually `!strchr(vow,x) == !strchr(vow,c)`). See http://stackoverflow.com/questions/1596668/logical-xor-operator-in-c – grek40 Jan 27 '17 at 06:36

1 Answers1

2

The program will not terminate unless I type EOF "^Z" on a new line. If I just add it at the end of the string, it will continue.

This is a windows command prompt issue. The Ctrl+z is not really EOF, it is just a signal for the command prompt that is interpreted as EOF when it appears solo in a line. If you feed the program stdin from terminal input and not from a file, reaching EOF is not generally available.

I suggest you live with this issue and create some sample.txt file as input. Then you can redirect stdin to read from this file and it will encounter EOF whenever the whole file was read.

I need a way to check if the last character printed is '_', and to remove it if it is at the end of the printed string.

Don't.

Instead of printing and removing, you could keep some boolean value that indicates whether a _ should be printed before the next alphanumeric character. But you only ever print it, if there actually is a next character to be printed.

int printSeparator = 0;
// ...

    if(isalpha(c))
    {
        if (printSeparator)
        {
            putchar('_');
            printSeparator = 0;
        }
        if (((strchr(vow,x)&&strchr(vow,c))||(!strchr(vow,x)&&!strchr(vow,c)))&&x!=0)
        {
            putchar(c);
            //putchar('_');
            printSeparator = 1;
            nr++;
            x=0;
        }
        else
        {
            putchar(c);
            x=c;
        }
    }

You may want to move the nr++ counter to the same place where the _ character is printed.

grek40
  • 13,113
  • 1
  • 24
  • 50