Scanf()函数不接受字符串输入

时间:2017-04-29 22:05:12

标签: c

在获取测试用例输入后,它不会等待字符串输入。我试过fgets();但是,fgets()需要用户的换行符,我认为不会被在线评委接受。那么,这里的问题是什么?这是我的代码。

  #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;
  }

3 个答案:

答案 0 :(得分:4)

更改

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

scanf(" %100[^\n]", s);
  • 开头的空格使它跳过单词之前的任何空格。这需要它允许它在扫描下一行之前读取每行末尾的换行符。
  • 100确保它不会尝试写过字符串的结尾。
  • 您最后不应该有s,因为这会尝试匹配输入中的文字s[^\n]不是%s格式运算符的修饰符,它是一个完全不同的格式运算符。

答案 1 :(得分:1)

如果您包含指向特定问题的链接,那将会非常有用。然后我们可以建议您是否正确回答了问题。

例如,大写字母,标点符号等等?

例如,问题是否保证每个输入字符串将<= 100个字符,或者是否存在不超过前100个字符的条件?

如果我们不知道问题是什么,我们无法确定发布的代码是否正在回答问题。

大多数I / O的时间/ CPU周期非常昂贵,尤其是scanf()printf()

大多数在线问题都有执行时间,超过允许的时间限制将导致建议的答案(您提供的)失败。

适当的快速&#39;通过查看先前问题的答案,您可以轻松找到I / O功能。以下是一些功能齐全的示例,可帮助您入门:

#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

大多数情况下(您可能需要进行一些实验)在线代码判断在每个测试用例(包括最后一个测试用例)之后需要将换行符输出到stdout。这通常通过以下方式完成:

putchar_unlocked('\n');

当值永远不会小于0时,(通常)最好使用size_t而不是int

使用指示contentusage(或更好,两者)的变量名称是一种很好的编程习惯。

如果

代码更具可读性和可理解性

  1. 一直缩进
  2. 代码块由单个空行分隔
  3. 使用有意义的变量名称
  4. 所有&#39; distractor&#39;代码被删除
  5. 将上述所有内容放在一起会导致:

    #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;
    }
    

    使用对printf()fastWrite()

    的一系列调用,也可以大大加快对putchar_unlocked()的通话速度

    此外,除非问题特别要求在printf()的调用中使用多余的字符,否则代码可能会说:

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

    还非常希望在代码顶部列出问题的参数。这既可以帮助您和其他任何人阅读您的代码。

    以下是此类文档的一个简单示例:

    /*
     * 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
     */
    

答案 2 :(得分:0)

鉴于您提供的最新信息,以下是我建议的答案。

如果仍未通过判决,至少你有一个非常坚实的基础,可以通过实验来确定正确的答案。

/*
 * 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