C++之文字列输入输出

时间:2022-06-18 01:23:07

目录

在屏幕上输出字符串

cout

flush、endl

coutの関数

接收键盘输入

输入错误检查

cin.fail関数

cin.clear関数

cin.ignore関数

指定流的最大值

接收字符串时的错误检查

setw

cinの関数

cin.getline関数


在屏幕上输出字符串

//使用C语言的输入输出函数(例如printf)所需
#include <stdio.h>

//使用C++输入/输出对象所需
#include <iostream>

int main()
{
    printf("printf输出\n");

    //C++的写法
    std::cout << "cout输出\n";

    getchar();
}

实行结果 

printf输出
cout输出

cout

cout不是函数,而是类的C++功能。

cout使用“<<”符号输出字符串。使用与移位运算符相同的符号,但功能不同。指定要在“std::cout<<”之后输出的字符串。

要在printf函数中显示变量的内容,可以使用转换指定符(格式字符串)指定参数的类型,但在cout中可以直接记述。但是,只能输出int和double等基本数据类型和一部分C++类,自制的数据类型(结构体等)不能直接输出。

#include <stdio.h>
#include <iostream>

int main()
{
    const char *str1 = "Hello";
    const char *str2 = "World";
    int number = 10;

    printf("%s %s %d\n", str1, str2, number);

    //字符串和数字都可以直接输出
    std::cout << str1 << " " << str2 << " " << number << "\n";

    getchar();
}

实行结果

Hello World 10
Hello World 10

flush、endl

cout也可以与flushendl等关键词一起使用。这些也需要“std::”作为开头。

#include <stdio.h>
#include <iostream>

int main()
{
    std::cout << "ABCDE\n";
	
    //刷新缓冲区
    std::cout << "ABCDE\n" << std::flush;
	
    //换行并刷新
    std::cout << "ABCDE" << std::endl;

    getchar();
}

缓冲区是指暂时储存数据的区域。(储存在缓冲器中称为缓冲)
cout等输出流在执行函数的同时,不是在画面上显示文字,而是暂时在缓冲区中存储数据。然后,当缓冲区已满或发出清除缓冲区的指示时,将输出数据,在画面上显示文字。

从缓冲区中清除数据称为缓冲区的刷新。上例的“std:flush”指示将缓冲区中积存的数据扫出来,在画面上显示文字。

“std::endl”也会刷新缓冲区,但最后插入换行符这一点不同。也就是说,字符串的最后可以不加“\n”。

coutの関数

cout使用<<运算符输出字符,但也可以使用cout中提供的函数。

#include <stdio.h>
#include <iostream>

int main()
{
    //单字输出
    std::cout.put('A');
    std::cout.put('\n');

    //字符串输出
    std::cout.write("ABCDE\n", 6);
    std::cout.write("ABCDE\n", 3);

    getchar();
}

实行结果

A
ABCDE
ABC

cout.put是输出单个字符的函数。等同于C语言中的putchar函数。

cout.write是一个输出字符串的函数。与C语言的puts函数相似,但第二参数指定要输出的字符数。如果指定的值小于第一参数,则字符串将在中途中断。相反,指定大值时的动作未定,所以要避免。

另外,使用“<<”运算符输出时,数值等也可以直接输出,但这些函数只能输出文字、字符串

接收键盘输入

使用cin从标准输入接收输入。

#include <stdio.h>
#include <iostream>

int main()
{
    int number;
    char str[100];

    std::cin >> number;
    std::cin >> str;

    std::cout << "\nnumber: " << number << std::endl;
    std::cout << "str: " << str << std::endl;

}

cin使用“>>”运算符,与cout运算符相反。

cin也和cout一样,无论变量的数据类型如何,都可以接收数据。但是,当然,即使想在整数型变量中输入字符串也不能接受。您也不能接收超过预先准备的字符串数组元素数的字符串。(缓冲区超限运行)因此,需要进行错误处理。

输入错误检查

#include <stdio.h>
#include <iostream>

int main()
{
    int number;

    while (1)
    {
        std::cout << "输入整数" << std::endl;
        std::cin >> number;

        if (std::cin.fail())
        {
            std::cout << "输入错误!\n" << std::endl;
            std::cin.clear();
            std::cin.ignore(1024, '\n');
            continue;
        }
        break;
    }
    
    std::cin.ignore(1024, '\n');
    std::cout << "\nnumber: " << number << std::endl;

    getchar();
}

cin.fail関数

cin内部有数据接收的成功和失败的状态,收到键输入后会根据情况改变状态。检查该状态的是cin.fail函数。顾名思义,如果接收失败,则为真。
返回状态的函数包括:

good()

正常状态(无错误)

eof()

文件结束

fail()

读取失败

bad()

其他错误

cin.clear関数

当cin处于某种错误状态后,状态不会自动恢复到正常状态。将状态恢复为good的是cin.clear函数。

如果忘记了这一点,下一次尝试通过cin输入时也会保持错误状态。在错误状态下,cin不接受输入,处理被忽略。结果会陷入无限循环。

cin.ignore関数

如果出现输入错误,则此时停止输入。也就是说,输入流中可能仍有未读取的数据。在这种状态下,如果下一次在cin中接收输入,则不会等待按键输入,就会读取剩余的数据。因为这样不方便,所以把不需要的数据扔掉。为此使用的是cin.ignore函数。

当省略第一参数调用cin.ignore函数时,将自动设置“1”。同样,如果省略第二参数,则会自动设置“traits_type:eof()”。(这表示数据的端点)

因为不知道输入流中还剩多少个字符,所以在第一参数中指定大的值,有富余地读取数据。控制台输入的最后一定是换行字符,所以在第二参数中指定换行字符,检测到换行字符后结束读取处理。

指定流的最大值

上面读到第1024个字符,但可能会输入更多。如果不安,用std::numeric_limits<std::streamsize>::max()可以设置流中可输入的最大字符数。

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

接收字符串时的错误检查

在char型数组中接收字符串时,必须注意缓冲区溢出。可以使用std:setw来避免接收超过已准备数组的元素数的字符。

#include <stdio.h>
#include <iostream>
#include <iomanip>

int main()
{
    char str[32];

    std::cout << "输入字符串" << std::endl;

    //限制32个字符或更多字符的输入
    std::cin >> std::setw(32) >> str;

    std::cout << "\nstr: " << str << std::endl;

    std::cin.ignore(1024, '\n');
    getchar();
}

setw

要使用setw,请包含iomanip。setw是与std::endl等相同的操纵器的一种。操纵器控制输入/输出流的行为。 

通过在向字符串数组输入数据之前在setw中指定输入字符数,可以防止输入更多的字符数。但是,字符串数组的结尾是空字符,因此实际输入的字符数为负1个字符。如果使用C++的string类,则输入与指定数字相同的字符数。 剩余的数据仍保留在输入流中,如果有再次输入处理,请用cin.ignore函数废弃。

cinの関数

#include <iostream>

int main()
{
    int c1;
    char c2;

    std::cout << "输入文字" << std::endl;
    c1 = std::cin.get();

    std::cout << "输入文字" << std::endl;
    std::cin.ignore(1024, '\n');
    std::cin.get(c2);

    std::cout << "\n输入的字符\n";
    std::cout << (char)c1 << "\n";
    std::cout << c2 << std::endl;

    std::cin.ignore(1024, '\n');
    std::cin.get();
}

int get();从输入流读取一个字符。返回值是读取的字符。

cin.get函数是从输入流中接收一个字符的函数。与C语言的getchar函数相同,但也可以将字符指定为参数。到目前为止,在代码的末尾使用C语言的getchar函数作为输入待机用,但这也被cin.get函数代替。因此,不需要包含stdio.h。

实际上,因为在iostream中包含了stdio.h,所以如果包含iostream的话,即使不特意包含stdio.h也可以使用printf函数等。

cin.get函数仍然存在过载。

#include <iostream>

#define BUFFER 32

int main()
{
    char str1[BUFFER];
    char str2[BUFFER];

    std::cout << "输入字符串" << std::endl;
    std::cin.get(str1, BUFFER);

    std::cout << "输入字符串" << std::endl;
    std::cin.ignore(1024, '\n');
    std::cin.get(str2, BUFFER, '\n');

    std::cout << "\n输入的字符串\n";
    std::cout << str1 << "\n";
    std::cout << str2 << std::endl;

    std::cin.ignore(1024, '\n');
    std::cin.get();
}

第一参数指定字符串数组。
第二参数指定字符串数组的大小(要读取的字符数)。
这样第一参数就可以从输入流接收字符串。
但是,因为最后有空字符,所以实际上可以读取少一个字符的字符数。
如果省略第三个参数,则直到出现换行符时才读取。
也可以为第三参数指定其他字符。

cin.getline関数

#include <iostream>

#define BUFFER 32

int main()
{
    char str1[BUFFER];
    char str2[BUFFER];

    std::cout << "输入字符串" << std::endl;
    std::cin.getline(str1, BUFFER);
    if (!std::cin.good())
    {
        std::cin.clear();
        std::cin.ignore(1024, '\n');
    }

    std::cout << "输入字符串" << std::endl;
    std::cin.getline(str2, BUFFER, '\n');
    if (!std::cin.good())
    {
        std::cin.clear();
        std::cin.ignore(1024, '\n');
    }

    std::cout << "\n输入的字符串\n";
    std::cout << str1 << "\n";
    std::cout << str2 << std::endl;

    std::cin.get();
}

这与在cin.get函数中指定两个或三个参数时的动作几乎相同。

与get函数的不同之处在于,get函数不读取终端字符(留在输入流中),getline函数读取终端字符。
因为get函数没有读取结束字符(\n)而留在输入流中,所以在下次使用get函数之前,如果不将输入流清空,就会出现什么都不能输入的现象。

getline函数读取到结束字符。如果输入的字符数大于或等于数组大小,cin将处于错误状态,因此清除状态并清空输入流。