笔记——字符串输入的细节问题

来源:互联网 发布:工作提醒软件 编辑:程序博客网 时间:2024/06/06 17:03

首先附上最近一次比赛的题目一枚

This week, CSDN network's database was hacked by somebody and six million usernames and passwords have been spread through Internet. As a programmer who registered on CSDN in the past, is your password safe now? 

You task is to judge whether a user's password has been leaked.

Input

Multiple test cases.

The first line contains a number T (1 <= T <= 10) specifying the number of test cases.

For each test case, the first line contains the number N ( 1 <= N <= 100) which means there are N users' password have been leaked. Then, N lines follows. Each line contain a user's username whose length is not larger than 10(Lower case latin letter only).

Then, one line contains a number Q  (1 <= Q <= 100)which means the number of queries. Next, Q lines follows. Each line contain a user's username whose length is not larger than 10(Lower case latin letter only).

Output

For each query, if the user's password is leaked, output "YES", otherwise output "NO". 

Output a blank line after each test case.

Sample Input

1

7

icek

falls

in

love

with

milk

tea

2

milky

icek

Sample Output

NO

YES

错误代码:

#include<iostream>

#include<string>

using namespace std;

char st[101][11];

char ss[101][6];

int n;

int tru(char tt[])

{

        int i;

        for(i=0;i<n;i++)

        {

                if((strcmp(tt,st[i]))==0)

                        return 1;

        }

        return 0;

}

int main()

{

        int m,i,q;

     char tt[11];

        cin>>m;

        for(i=1;i<=m;i++)

        {

                int j,k;

               cin>>n;

                for(j=0;j<n;j++)

                     gets(st[j]);

               cin>>q;

                for(j=0;j<q;j++)

                {

                        gets(tt);

                        if(tru(tt))

                                strcpy(ss[j],"YES");

                        else

                                strcpy(ss[j],"NO");

                }

                for(j=0;j<q;j++)

                                puts(ss[j]);

                printf("\n");

        }

        return 0;

 

}

这是个错误的代码,当运行此程序时

仅仅输入完

1

7

icek

falls

in

love

with

milk

tea

就自动输出一个回车,程序便运行结束了。

为什么?研究完了大家就知道了。

(阅读下文,请一定注意输出时的空格)

字符串输入

1.gets()

stdin流中读取字符串,直至接收到换行符或者EOF,。换行符可被读入,但是不作为读取串的内容,读取的换行符被转换为null值,并由此来结束字符串。(由于本函数可以无限读取,不会判断上限,所以须保证空间够大,否则将会溢出。为了避免此种情况,一般改用fgets().
2.fgets()
   fgets()
的第三个参数说明读哪个文件。从键盘上读数据时,可以使用stdin(代表standard input)作为参数。

其行为方式如下:

1)遇到换行或文件结束EOF则返回。

2)按行读取。

3)每一行结束处的换行字符‘\n’也算该行字符,而不是像gets()那样丢弃它。

4)对于大小为sizebuf,最多只读取size-1个字符。

5)自动地把buf中最后一个字符(通常是换行符)的后面一个字节填充零结束符('\0')。 因此如果想把buf中的换行符去掉,可以这样:buf[strlen(buf)-1] = '\0';当前前提是buf足够大,可以容纳完整的一行(包括最后的那个换行符)。

3.scanf()
  scanf()
允许指定输入字符串长度等格式。

scanf()不接受空格、制表符、回车等,遇到回车时,停止,并且回车依然留在输入流中,所以,如果有多个输入函数被调用时,要注意对多余回车的读取。

例如:

#include<stdio.h>

int main()

{

   char s1[10],s2[10];

   scanf(“%s”,s1);

   gets(s2);

   puts(s1);

   puts(s2);

return 0;

}

当输入hello hello↙时输出

hello

 hello

当输入hello↙时输出

hello


gets()
fgets()函数是收回车的(但是有区别),而scanf()不接收回车(现在学习的cin也是直接跳过空白符包括回车)。


字符串输出:
1.puts()
puts()
显示字符串时自动在其后添加一个换行符。
2.fputs()
   

int fputs(char *string,FILE *stream);

string是要写入文件的字符串。

*fputs()第二个参数表示要写的文件。
*fputs()
不自动输出换行符,这与puts()不太相同。
3.printf()

 

另外附上cin相关的用法:

    cin>>

a)最常用的输入一个数字:

#include<iostream>

using namespace std;

int main()

{

   int a;

char st[5];

   cin>>a;

gets(st);

   cout<<a<<endl;

puts(st);

return 0;

}

当我们输入:2 ss↙时输出:2 ss

此时,>>是会跳过不可见字符(如空格,回车,TAB等等)

b)接收一个字符串

接收一个字符串,遇上空格,TAB,回车等均结束,并且不读入他们。

#include<iostream>

using namespace std;

int main()

{

 char s1[10],s2[10];

cin>>s1;

gets(s2);

cout<<s1<<endl;

puts(s2);

return 0;

}

当我们输入hello hello↙时,输出hello hello

当我们输入hello↙时直接输出hello↙↙

     cin.get()

    接收字符

#include<iostream>

using namespace std;

int main()

{

char st;

ch=cin.get();

cout<<ch<<endl;

return 0;

}

    接收字符串(可以接收空格,不接收(跳过)回车)

#include<iostream>

using namespace std;

int main()

{

char s1[10],s2[20];

cin.get(s1,10);

gets(s2);

cout<<s1<<endl;

puts(s2);

return 0;

}

当我们输入hello↙时直接输出hello↙↙

当我们输入hi hi↙时则输出hi hi↙↙

     cin.getline()

接收一个字符串(可接收空格,接收但是回车(同gets()))

#include<iostream>

using namespace std;

int main()

{

 char s1[10],s2[10];

cin.getline(s1,9);

gets(s2);

puts(s1);

puts(s2);

return 0;

}

当我们输入hello hi↙后可以继续输入,接着输入hi↙输出hello hihi

现在分析一下文首的代码错误,首先,读入m时,跳过一个回车,然后输入n时也跳过一个回车,接着第一个gets()实际上仅仅读到了回车并且丢弃,后来的六个gets()则读入了相关的字符串,并且丢弃了最后的回车。而后读入q时,读的仍然是剩下的字符串tea,读入失败,返回一个负值,则直接跳过了下面的循环,执行了最后的输出回车。

所以联系刚才研究的,需要次修改:
即在每个cin后面都加上一句getchar()

 

以上内容为个人整理总结,希望对大家有所帮助,有任何错误也请批评指正,谢谢!!

原创粉丝点击