2
\$\begingroup\$

For example, sequence "aasdf123456785fg87" will be transformed into "aasdf12345678fg", using getchar and putchar and then using strings.

With getchar and putchar:

char c = 0, c_ = 0;
char flag = 0;
while ((c = getchar()) != '.')
{
    if (isdigit(c))
    {
        if (!isdigit(c_))
        {
            flag = 0;
            c_ = c;
            while (true)
            {
                c = getchar();
                if (!isdigit(c))
                {
                    if (flag)(putchar(c_));
                    putchar(c);
                    break;
                }

                if (c - c_ == 1)
                {
                    flag = 1;
                    putchar(c_);
                }
                c_ = c;
            }
        }
    }
    else putchar(c);

    c_ = c;
}

and using strings:

char str[100] = { 0 }, outstr[100] = { 0 };
int i = 1;
char flag = 0;
int c = 0;
gets(str);
while (true)
{
    if (isdigit(str[i]))
    {
        if (isdigit(str[i - 1]))
        {
            if (str[i] - str[i - 1] == 1)
            {
                outstr[c++] = str[i - 1];
                flag = 1;
            }
            else
            {
                if (flag)outstr[c++] = str[i - 1];
                flag = 0;
            }
        }
    }
    else
    {
        if (flag)
        {
            outstr[c++] = str[i - 1];
            flag = 0;
        }
        if (str[i] == '.')break;
        outstr[c++] = str[i];
    }
    i++;
}
puts(outstr);

This code is not great, and I ask you to make it easier to understand and more effective. The thing is that I need to show these programs to my teacher, and he's going to see them done as easier and smarter as possible. I just don't know if it's okay.

\$\endgroup\$
1
  • \$\begingroup\$ If you've covered that bit, you must remove this code to a function. Also I don't understand what you're doing with '.'. If the string contains period ('.') the loop terminates and outstr won't be properly terminated with a '\0'. Should that check not be for a '\0'? \$\endgroup\$
    – user59064
    Dec 15 '14 at 8:07
1
\$\begingroup\$

Review of the getchar and putchar: portion

  1. Testing the "With getchar and putchar:" code would be easier if given a function declaration to see clearly what are inputs and outputs. Example:

    void UpdigitsFilter_IO(void) {
    // or
    int UpdigitsFilter_IO(void) {
    
  2. Code uses '.' as a terminator, but that is not listed as a design criteria. Was this to be '\0'?

  3. Code uses char c, whereas getchar() returns an int. This causes issues in 2 places, when EOF is encountered and char outside the 0 - SCHAR_MAX (typically 127). Proper use of is...() functions require values in the 0 to UCHAR_MAX range or EOF.

    // char c = 0;
    int c = 0;
    
  4. Exiting the loop on EOF should occur (2x places)

    // while ((c = getchar()) != '.')
    while ((c = getchar()) != '.' || c == EOF)
    
  5. There is a discrepancy between "ascending digits" and if (c - c_ == 1). The first implies "135" is acceptable as the digits are greater than previous, but code implies they need to be sequential. Assume sequential.

  6. The requirements are silent on single digits sequences. Assume acceptable.

  7. Check the return value of putchar(). Maybe make this the function's return when non-zero.

    int retval = putchar(ch);
    if (retval) {
      return retval;
    }
    
  8. Filtering will not stop if a '.' is encountered in the inner c = getchar();. Add checks here for '.' and EOF.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.