0

After taking test case inputs it does not waits for string input. I have tried fgets(); But, fgets() requires a newline from user which i think will not be accepted by online judge. So, whats the problem here ? Here is my code.

  #include<stdio.h>

 int main ()
 {
int t, j;
int cnt = 0;
scanf("%d", &t);

while(t--)
{
    cnt++;

    int i, count = 0;

    char s[101];

    scanf("%[^\n]s", s);



    for(i=0;s[i] != '\0'; i++)
    {
        if(s[i] == 'a' || s[i] == 'd' || s[i] == 'g' || s[i] == 'j' || s[i] == 'm' || s[i] == 'p' || s[i] == 't' || s[i] == 'w' || s[i] == ' ')
        {
            count += 1;
            continue;
        }
        else if(s[i] == 'b' || s[i] == 'e' || s[i] == 'h' || s[i] == 'k' || s[i] == 'n' || s[i] == 'q' || s[i] == 'u' || s[i] == 'x')
        {
            count += 2;
            continue;
        }
        else if(s[i] == 'c' || s[i] == 'f' || s[i] == 'i' || s[i] == 'l' || s[i] == 'o' || s[i] == 'r' || s[i] == 'v' || s[i] == 'y')
        {
            count += 3;
            continue;
        }
        else if(s[i] == 's' || s[i] == 'z')
        {
            count += 4;
            continue;
        }

    }

    printf("Case #%d: %d\n", cnt, count);

}
 return 0;
  }
4
  • 3
    Why do you have s after %[^\n]? That can't work, becaue %[^\n] stops reading when it gets to a newline character, and then the next character can't be s because it's newline. Commented Apr 29, 2017 at 22:09
  • 1
    scanf("%[^\n]s", s); -> scanf("%100[^\n]", s); - As per the manual page. Also perhaps using switch might make the code more readable Commented Apr 29, 2017 at 22:10
  • You should also put a space at the beginning of the pattern, so when you call it again it will skip over the newline. Commented Apr 29, 2017 at 22:11
  • If user input was only spaces, what would you hope scanf("%[^\n]s", s); would do? Commented Apr 30, 2017 at 21:22

3 Answers 3

6

Change

scanf("%[^\n]s", s);

to

scanf(" %100[^\n]", s);
  • The space at the beginning makes it skip over any whitespace before the word. This is needed to allow it to read past the newline at the end of each line before scanning the next line.
  • 100 ensures that it doesn't try to write past the end of the string.
  • You shouldn't have s at the end, because that will try to match a literal s in the input. [^\n] is not a modifier of the %s format operator, it's a completely different format operator.
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. Thank you very much. I am learning newer things day by day. You solution helped.
@AdibHasib Buy or get it online C Programming: A Modern Approach Second Edition, it is very very good.
1

It would help immensely if you had included a link to the specific question. Then we could advise if you had answered the question correctly.

For instance, what about capital letters, punctuation, etc.?

For instance, does the question guarantee that each input string will <= 100 characters, or is there a criteria that no more than the first 100 characters be used?

We cannot determine if the posted code is answering the question if we do not know what the question is.

Most I/O is very time/CPU cycles expensive, especially scanf() and printf()

Most online questions have the execution timed and exceeding the allowed time limit will cause the proposed answer (that you provide) to fail.

Appropriate 'fast' I/O functions are easily found by YOU by looking at the answers to prior questions. Here are a couple of fully functional examples to get you started:

#include <stdio.h>

void fastRead( size_t *a );
void fastWrite( size_t a );

inline void fastRead(size_t *a)
{
    int c=0;
    // note: 32 is space character
    while (c<33) c=getchar_unlocked();

    // initialize result value
    *a=0;

    // punctuation parens, etc are show stoppers
    while (c>47 && c<58)
    {
        *a = (*a)*10 + (size_t)(c-48);
        c=getchar_unlocked();
    }
    //printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead


inline void fastWrite(size_t a)
{
    char snum[20];
    //printf( "%s, %lu\n", __func__, a );

    int i=0;
    do
    {
        // 48 is numeric character 0
        snum[i++] = (char)((a%10)+(size_t)48);
        a=a/10;
    }while(a>0);

    i=i-1; // correction for overincrement from prior 'while' loop

    while(i>=0)
    {
        putchar_unlocked(snum[i--]);
    }
    putchar_unlocked('\n');
} // end function: fastWrite

Most often (you may have to experiment a bit) the online code judging wants a newline output to stdout after each test case, including the last test case. This is usually accomplished by:

putchar_unlocked('\n');

When a value will never be less than 0, it is (usually) best to use size_t rather than int,

It is good programming practice to use variable names that indicate content or usage (or better, both).

code is MUCH more readable and understandable if

  1. it is consistently indented
  2. code blocks are separated by a single blank line
  3. meaningful variable names are used
  4. all 'distractor' code is eliminated

Putting all the above together results in:

#include <stdio.h>   // putchar_unlocked(), getchar_unlocked()

void fastRead( size_t *a );
void fastWrite( size_t a );

inline void fastRead(size_t *a)
{
    int c=0;
    // note: 32 is space character
    while (c<33) c=getchar_unlocked();

    // initialize result value
    *a=0;

    // punctuation parens, etc are show stoppers
    while (c>47 && c<58)
    {
        *a = (*a)*10 + (size_t)(c-48);
        c=getchar_unlocked();
    }
    //printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead


inline void fastWrite(size_t a)
{
    char snum[20];
    //printf( "%s, %lu\n", __func__, a );

    int i=0;
    do
    {
        // 48 is numeric character 0
        snum[i++] = (char)((a%10)+(size_t)48);
        a=a/10;
    }while(a>0);

    i=i-1; // correction for overincrement from prior 'while' loop

    while(i>=0)
    {
        putchar_unlocked(snum[i--]);
    }
    putchar_unlocked('\n');
} // end function: fastWrite


int main ( void )
{
    size_t numTestCases;

    fastRead( &numTestCases );

    for( size_t testCase =1; testCase <= numTestCases; testCase++)
    {
        size_t count = 0;
        int ch;
        while( (ch = getchar_unlocked()) != '\n' )
        {
            if(    ch == 'a'
                || ch == 'd'
                || ch == 'g'
                || ch == 'j'
                || ch == 'm'
                || ch == 'p'
                || ch == 't'
                || ch == 'w'
                || ch == ' ')
            {
                count += 1;
            }

            else if(   ch == 'b'
                    || ch == 'e'
                    || ch == 'h'
                    || ch == 'k'
                    || ch == 'n'
                    || ch == 'q'
                    || ch == 'u'
                    || ch == 'x')
            {
                count += 2;
            }

            else if(   ch == 'c'
                    || ch == 'f'
                    || ch == 'i'
                    || ch == 'l'
                    || ch == 'o'
                    || ch == 'r'
                    || ch == 'v'
                    || ch == 'y')
            {
                count += 3;
            }

            else if(   ch == 's'
                    || ch == 'z')
            {
                count += 4;
            }
        }

        printf("Case #%lu: %lu\n", testCase, count);

        putchar_unlocked( '\n' );
    }
    return 0;
}

The call to printf() could also be greatly sped up by using a series of calls to fastWrite() and putchar_unlocked()

Also, unless the question specifically asks for the superfluous characters being used in the call to printf() the code probably should say:

fastWrite(  testCase );
putchar_unlocked( ' ' );
fastWrite(  count );
putchar_unlocked( '\n' );

it is also highly desirable to list the parameters of the question at the top of your code. This both helps you and anyone else reading your code.

Here is a trivial example of such documentation:

/*
 * criteria 1
 * Using two characters: . (dot) and * (asterisk)
 * print a frame-like pattern
 *
 * criteria 2
 * You are given t - the number of test cases
 *
 * criteria 3
 * for each of the test cases input two positive integers:
 *     l - the number of lines and
 *     c - the number of columns of a frame.
 *
 * criteria 4
 * Use one line break in between successive patterns
 */

1 Comment

uva.onlinejudge.org/… Here is the problem i was solving
0

Given the latest information you have provided, here is the answer that I would suggest.

If it still does not pass the judge, at least you have a very solid base from which to experiment to determine the correct answer.

/*
 * Cell phones have become an essential part of modern life.
 * In addition to making voice calls,
 * cell phones can be used to send text messages,
 * which are known as SMS for short.
 * Unlike computer keyboards, most cell phones have limited number of keys.
 * To accommodate all alphabets, letters are compacted into single key.
 * Therefore, to type certain characters,
 * a key must be repeatedly pressed until that character is shown on the display
panel.
 *
 * In this problem we are interested in  finding out the number of times
 * keys on a cell phone must be pressed to type a particular message.
 * In this problem we will assume that the key pad of our cell phone is arranged as follows.
 * ---------------------
 * |1     | abc | def  |
 * ---------------------
 * | ghi  | jkl | mno  |
 * ---------------------
 * | pqrs | tuv | wxyz |
 * ---------------------
 * |      | <SP>|      |
 * ---------------------
 * In the above grid each cell represents one key.
 * Here <SP> means a space.
 * In order to type the letter `a', we must press that key once,
 * however to type `b' the same key must be pressed twice
 * and for `c' three times.
 * In the same manner, one key press for `d',
 * two for `e'
 * and three for `f'.
 * This is also applicable for the remaining keys and letters.
 * Note that it takes a single press to type a space.
 *
 * Input
 * The  first line of input will be a positive integer T
 * where T denotes the number of test cases.
 * T lines will then follow each containing only spaces and lower case letters.
 * Each line will contain at least 1 and at most 100 characters.
 *
 * Output
 * For every case of input there will be one line of output.
 * It will  first contain the case number
 * followed by the number of key presses required to type the message of that case.
 *  Look at the sample output for exact formatting.
 *
 * Sample Input
 * 2
 * welcome to ulab
 * good luck and have fun
 *
 * Sample Output
 *
 * Case #1: 29
 * Case #2: 41
 */

#include <stdio.h>   // putchar_unlocked(), getchar_unlocked(), puts(), sprintf()
#include <string.h>  // strcpy(), strcat()

#define MAX_OUTPUT_LEN 50

void fastRead( size_t *a );
void fastWrite( size_t a );

inline void fastRead(size_t *a)
{
    int c=0;
    // note: 32 is space character
    while (c<33) c=getchar_unlocked();

    // initialize result value
    *a=0;

    // punctuation parens, etc are show stoppers
    while (c>47 && c<58)
    {
        *a = (*a)*10 + (size_t)(c-48);
        c=getchar_unlocked();
    }
    //printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead


inline void fastWrite(size_t a)
{
    char snum[20];
    //printf( "%s, %lu\n", __func__, a );

    int i=0;
    do
    {
        // 48 is numeric character 0
        snum[i++] = (char)((a%10)+(size_t)48);
        a=a/10;
    }while(a>0);

    i=i-1; // correction for overincrement from prior 'while' loop

    while(i>=0)
    {
        putchar_unlocked(snum[i--]);
    }
    putchar_unlocked('\n');
} // end function: fastWrite


const size_t keyPressCounts[] =
{
    1, 2, 3,   // a b c
    1, 2, 3,   // d e f
    1, 2, 3,   // g h i
    1, 2, 3,   // j k l
    1, 2, 3,   // m n o
    1, 2, 3, 4,// p q r s
    1, 2, 3,   // t u v
    1, 2, 3, 4 // w x y z
};


int main ( void )
{
    size_t numTestCases;

    fastRead( &numTestCases );

    for( size_t testCase =1; testCase <= numTestCases; testCase++)
    {
        size_t keypresses = 0;
        int ch;

        while( (ch = getchar_unlocked()) != '\n' )
        {
            if( ' ' == ch )
                keypresses += 1;
            else
                keypresses += keyPressCounts[ ch - 'a' ];
        } // end while()

        char outputLine[ MAX_OUTPUT_LEN ];
        strcpy( outputLine, "Case #" );
        sprintf( &outputLine[ strlen(outputLine) ], "%lu", testCase );
        strcat( outputLine, ": " );
        sprintf( &outputLine[ strlen(outputLine) ], "%lu", keypresses );
        puts( outputLine );
    } // end for()

    return 0;
} // end function: main

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.