C++中数据的输入输出总结(修订)

C++中数据的输入输出总结

本文作为 “C++语言之输入输出深入介绍” https://blog.csdn.net/cnds123/article/details/126358415 的补充总结。

C++中数据的输入输出涉及到的头文件

<iostream>:这是C++标准库中最常用的头文件之一,包含了进行标准输入输出操作的类和对象,如std::cin、std::cout、std::endl等。

<iomanip>:该头文件提供了一些用于控制输入输出格式的函数和流控制符,比如std::setprecision、std::setw、std::fixed等。

<fstream>:这个头文件用于文件输入输出操作。它提供了用于读写文件的输入输出流类,如std::ifstream、std::ofstream等。

<sstream>:该头文件定义了用于字符串流的类,如std::istringstream、std::ostringstream等。它们可以方便地将数据从字符串转换为其他类型,或者将其他类型的数据转换为字符串。

<cstdio>或<stdio.h>:这是C语言中的头文件,也可以在C++中使用。它提供了一些与C标准库相关的输入输出函数,如scanf、printf、fgets、fputs等。

需要根据实际需求选择合适的头文件来进行数据的输入输出操作。例如,如果只是进行标准输入输出,只需要包含<iostream>即可;如果需要读写文件,需要包含<fstream>;如果需要进行字符串流的操作,需要包含<sstream>等。

下面介绍几种C++中数据的输入输出几种基本方式。

使用<iostream>头文件的cin和cout对象及getline()函数

<iostream> 是 C++ 标准库中的头文件之一,用于输入输出操作。它定义了 std::cout、std::cin、std::cerr 和 std::clog 等流对象,以及与它们相关的函数,如 std::getline()等。https://cplusplus.com/reference/istream/iostream/

其中,std::cout 表示标准输出流,可以用于向屏幕或文件输出文本;std::cin 表示标准输入流,可以用于从键盘或文件读取文本;std::cerr 表示标准错误流,通常用于输出错误信息;std::clog 表示标准日志流,通常用于输出程序运行时的消息。

std::getline()函数可以从输入流中读取一行数据。

【iostream 和 istream 、 ostream的关系

https://cplusplus.com/reference/iolibrary/

在 C++ 标准库中,istream 和 ostream 是两个基础类,分别代表输入流和输出流。这些类提供了一系列方法,用于从流中读取数据(在 istream 的情况下)或向流中写入数据(在 ostream 的情况下)。

iostream 是一个头文件,它包含了 istream 和 ostream 的定义。这意味着,当你在你的程序中包含 iostream 头文件时,你可以使用 istream 和 ostream 类的功能,即可以进行输入和输出操作。

此外,iostream 还定义了一个 iostream 类,该类是 istream 和 ostream 的派生类,用于同时处理输入和输出流。这个类继承了 istream 和 ostream 的所有方法,并可能添加了一些额外的方法。

所以,istream 和 ostream 是处理输入和输出的基础类,iostream 是一个包含这两个类的头文件,并且还定义了一个同时处理输入和输出的类。】

cin和cout:这是C++标准库提供的输入输出流对象,用于从标准输入读取数据和向标准输出写入数据。例如,读入一个整数可以使用cin和>>运算符,输出一个整数可以使用cout和<<运算符:

#include <iostream>

int main() {
    int num;
    std::cout << "请输入一个整数: ";
    std::cin >> num;
    std::cout << "您输入的整数是: " << num << std::endl;

    return 0;
}

在上面的例子中,我们使用std::cin从标准输入读取一个整数,并使用std::cout将其输出到标准输出。

std::getline()函数可以从输入流中读取一行数据。

需要注意的是,在C++中,有两种getline函数。第一种定义在头文件<istream>中https://cplusplus.com/reference/istream/istream/getline/ ;第二种定义在头文件<string>中https://cplusplus.com/reference/string/string/getline/

<istream>中的getline()函数用于从输入流中读取一行文本,而<string>中的getline()函数用于从一个字符串中读取一行文本。它们的用法和参数略有不同,但功能类似。

<istream>中的getline()函数:getline()函数是istream类的一个成员函数,可以从输入流(如cin)读取一行文本并存储到一个std::string对象中。它的函数原型为:

istream& getline (char* s, streamsize n, char delim );

参数说明:

s:表示指向字符数组的指针,其中提取的字符存储为 c 字符串。

n:指定了字符数组s的最大长度。

delim:可选参数,表示行的分隔符,如果不指定,默认为换行符('\n')。

<istream>中的getline()函数用于读取一行文本,存储到字符数组中。

例如:

#include <iostream>   
using namespace std;
 
int main()
{
	char name[256];
	cout << "Please input your name: ";
	cin.getline(name, 256); // 从标准输入读取一行文本
	cout << "The result is:  " << name << endl;
  
    return 0; 
}

运行之:

<string>中的getline()函数:getline()函数是std::getline()函数的重载版本之一,用于从一个字符串中读取一行文本并存储到另一个std::string对象中。它的函数原型为:

std::istream& getline(std::istream& is, std::string& str, char delim);

参数说明:

is:输入流对象(可以是std::cin,也可以是一个std::istringstream)。

str:用于存储读取行的字符串对象。

delim:可选参数,表示行的分隔符,如果不指定,默认为换行符('\n')。

<string>中的getline()函数用于读取一行文本存储到一个std::string对象中。

例如

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string name;
    cout << "Please input your name: ";
    getline(cin, name); //从输入流读取一行文本
    cout << "Welcome to here!" << name << endl;
  
    return 0; 
}

运行之:

使用<cstdio>头文件的getchar 、 putchar及scanf、printf函数

<cstdio>头文件定义了一些函数和类型,如 printf()、scanf()、fgets()、fopen() 等,可以用于文件和标准输入输出流的读写操作。

【<cstdio>和<stdio.h>的关系

<stdio.h> 是 C 语言中的一个头文件,它包含了一些传统的输入输出函数,如 printf、scanf 等。在 C++ 中,应该使用 <cstdio>,<cstdio> 和 <stdio.h> 用于进行输入输出操作的两个头文件,语法和功能基本相同,可以相互替代使用。

C++ 中,<cstdio> 头文件是对 C 语言标准库中的 <stdio.h> 头文件的保留使用,它们的功能和语法几乎完全相同。因此,如果您正在编写 C++ 代码,并且需要进行流和文件的输入输出操作,那么您可以使用 <cstdio> 头文件来包含相关的函数和定义。】

getchar 和 putchar函数是两个常用的字符输入输出函数。

getchar() 函数用于从标准输入流(通常是键盘)读取单个字符。它不需要任何参数,并且会等待用户输入字符后才能继续执行程序。示例用法如下:

#include <cstdio>

int main() {
    char c = getchar(); // 从标准输入读取一个字符
    putchar(c); // 将字符输出到标准输出
    return 0;
}

putchar() 函数用于将一个字符输出到标准输出流(通常是控制台)。示例用法如下:

#include <cstdio>

int main() {
    char c = 'A';
    putchar(c); // 将字符 'A' 输出到屏幕
    return 0;
}

顺便提示:

getchar() 和 putchar() 最初设计用于处理 ASCII 字符,但它们也具备处理中文字符的功能。中文字符通常使用多字节编码(如UTF-8),怎么理解?

 getchar() 和 putchar() 函数可以处理中文字符,是因为它们是通过底层的操作系统或编译器提供的字符输入输出功能来实现的。底层的字符输入输出功能可能会根据不同的操作系统或编译器而有所差异,对于一些特殊的字符或编码方式,可能会出现问题。所以在处理中文字符时,最好使用支持中文字符的更高级的输入输出函数,如使用 <iostream> 头文件中的 std::cin 和 std::cout。

scanf和printf是C语言中常用的输入输出函数,也可以在C++中使用。scanf用于从标准输入读取数据,而printf用于向标准输出写入数据。如果要在C++中使用需要注意一些细节。一般情况下,scanf和printf可以和cin和cout等价地使用。例如,读入一个整数可以使用scanf,输出一个整数可以使用printf:

#include <cstdio>

int main() {
    int num;
    printf("请输入一个整数: ");
    scanf("%d", &num); // 读入一个整数
    printf("您输入的整数是: %d\n", num); // 输出一个整数到标准输出

    return 0;
}

需要注意的是,scanf和printf需要使用格式化字符串来指定输入输出的数据类型,因此需要多写一些代码。同时,scanf的输入参数需要使用"取地址符"&,而printf的输出参数不需要。

scanf和printf格式化输入输出介绍

scanf函数是用于格式化输入的函数,它可以从控制台或文件中按照指定的格式读取数据。

基本语法为:

scanf("格式控制字符串", 地址表达式1, 地址表达式2, ...);

其中,格式控制字符串用来指定要输入的数据类型和格式。地址表达式用来表示变量在内存中的地址,这样 scanf 函数才能将输入的数据存放到对应的变量中。

【scanf的返回值:scanf函数返回成功读取的输入项的数量。若返回值小于要求输入的参数数目,则说明读取失败。例如,若输入的格式控制字符串为"%d %d",则只有两个整数均成功读取并赋值给对应变量,才会返回2。】

格式控制字符串,包含了输入的格式。可以使用与printf相同的转换字符和格式化说明符来指定输入的类型。

下面是一些常用的格式符及其用法:

%d:读取一个有符号十进制整数。

示例:int num; scanf("%d", &num);

特别提示:取地址符"&"的作用是取变量的地址。地址标识内存的位置,相当于容器(如“盒子”)号码。假设有一个变量num,相当于名为num的容器,&num表示找到了这个容器的号码,就可以使用这个容器了。

%f:读取一个浮点数。

示例:float num; scanf("%f", &num);

%c:读取一个字符。

示例:char ch; scanf("%c", &ch);

%s:读取一个字符串。

示例:char str[100]; scanf("%s", str);

%lf:读取一个双精度浮点数。

示例:double num; scanf("%lf", &num);

%u:读取一个无符号十进制整数。

示例:unsigned int num; scanf("%u", &num);

%x:读取一个十六进制整数。

示例:int num; scanf("%x", &num);

%o:读取一个八进制整数。

示例:int num; scanf("%o", &num);

%p:读取一个指针。

示例:int* ptr; scanf("%p", &ptr);

%*d:跳过一个有符号十进制整数的读取,但不赋值给变量。

示例:scanf("%*d");

scanf函数的域宽(field width)参数必须是一个非负整数。下面是scanf函数的域宽(field width)的示例:

#include <cstdio> //或用#include <stdio.h>

int main() {
    int num; // 定义整数变量num
    char s[6]; // 定义字符数组s,可以存储5个字符和一个空字符

    printf("请输入一个整数:\n"); // 提示用户输入整数
    scanf("%4d", &num); // 读取用户输入的4位整数,存储在变量num中

    int c; // 定义整数变量c,用于接收getchar()读取的字符
    while ((c = getchar()) != '\n' && c != EOF); // 清空输入缓冲区,防止对后续字符串输入产生不良影响

    printf("请输入一个字符串:\n"); // 提示用户输入字符串
    scanf("%6s", s); // 读取用户输入的不超过6个字符的字符串,存储在字符数组s中

    printf("整数: %d\n", num); // 打印用户输入的整数
    printf("字符串: %s\n", s); // 打印用户输入的字符串

    return 0; // 程序结束,返回0表示正常退出
}

通过程序中的scanf函数来读取用户输入,%4d 用于只获取不超过4位的整数,%6s 用于只获取不超过6个字符的字符串,避免了用户输入过长的情况。同时,在读取完整数后通过while循环和getchar函数清空了输入缓冲区,避免了后续字符串读取出现异常。最后,将读取到的整数和字符串分别打印出来。

请注意,域宽参数是可选的,如果省略,则scanf函数将读取尽可能多的字符,直到遇到空格、制表符或换行符为止。

printf函数是用于格式化输出的函数,它可以将数据格式化输出到控制台或文件中。基本语法为:

printf("格式控制字符串", 值1, 值2, ...);

其中,值1、值2 等表示要输出的变量或常量,可以有多个。

"格式控制字符串"由两种类型的字符组成:普通字符和格式化指令。

【printf的返回值:printf函数返回成功打印(输出)的字符数量。如果发生错误,则返回负值。例如,如果使用printf输出了6个字符,则返回值为6。】

普通字符是指在格式控制字符串中直接显示的字符,不会影响输出的格式。

格式化指令由百分号(%)后面的字符组成,用于指定输出值的类型和格式。常用的格式化指令包括:

%d:以十进制整数的形式输出。

%f:以浮点数的形式输出。

%c:以字符的形式输出。

%s:以字符串的形式输出。

%p:以指针的形式输出。

%x:以十六进制数的形式输出。

在printf函数中,你可以使用精度和字段宽度等选项控制输出的位数和格式。

字段宽度(Field Width):可以使用数字来指定输出字段的最小宽度。如果输出的数据长度小于字段宽度,则会使用填充字符(默认为空格)在左侧或右侧进行填充。示例:

int num = 42;

printf("%5d\n", num); // 输出 "   42",字段宽度为5,右对齐

printf("%-5d\n", num); // 输出 "42   ",字段宽度为5,左对齐

精度(Precision):对于浮点数,可以使用.n的格式来指定小数点后的位数。对于字符串,可以使用.n来指定输出字符的最大数量。如果数据的长度超过了精度值,那么会截断超出部分,若不足默认补零。示例:

double pi = 3.1415926535;

printf("%.2f\n", pi); // 输出 "3.14",".2" 表示精度限制两位小数。"f" 则表示浮点数类型。

左对齐(Left Alignment)和零填充(Zero Padding):

可以使用-标志来指定输出左对齐。默认情况下,输出是右对齐的。

可以使用0标志来指定使用零进行填充字段宽度。默认情况下,使用空格进行填充。

左对齐和零填充示例:

int num = 42;

printf("%-5d\n", num); // 输出 "42   ",字段宽度为5,左对齐

printf("%05d\n", num); // 输出 "00042",字段宽度为5,零填充

十六进制前缀(Hexadecimal Prefix):对于以十六进制表示的整数,可以使用#标志来添加前缀0x或0X。示例:

int num = 42;

printf("%#x\n", num); // 输出 "0x2a",以十六进制表示并添加前缀

符号显示(Sign Display):可以使用+标志来显示正数的符号(+),而默认情况下只显示负数的符号(-)。符号显示示例:

int num1 = 42;

int num2 = -42;

printf("%+d\n", num1); // 输出 "+42",显示正数的符号

printf("%+d\n", num2); // 输出 "-42",显示负数的符号

下面是一个使用scanf和printf函数的完整示例:

#include <cstdio>

int main() {
    int num;
    printf("请输入一个整数: ");
    scanf("%d", &num);
    printf("您输入的整数是: %d\n", num);

    double floatingNum;
    printf("请输入一个浮点数: ");
    scanf("%lf", &floatingNum);
    printf("您输入的浮点数是: %.2f\n", floatingNum);

    return 0;
}

在这个示例中,首先使用 printf 输出提示信息,然后使用 scanf 从用户输入中读取数据。读取整数时,使用 %d 格式符,并通过 & 取地址操作符将变量的地址传递给 scanf;读取浮点数时,使用 %lf 格式符,同样需要使用 & 取地址操作符来传递变量地址。使用 printf 将读取到的数据格式化输出到屏幕上。注意,在输出浮点数时,我们使用了 %.2f 的格式控制,限制只显示两位小数。

【取地址符"&"的作用是取变量的地址。地址标识内存的位置,相当于容器(如“盒子”)号码。
假设有一个变量a,相当于名为a的容器,&a表示找到了这个容器的号码,就可以使用这个容器了。】

文件输入输出

C++中使用文件输入输出需要包含<fstream>头文件,常用的类包括ifstream(输入文件流)和ofstream(输出文件流)。可以使用它们来打开文件、读写文件、关闭文件——open、read、write和close函数等。)等操作。下面是一个将一个文件的内容复制到另一个文件中的示例代码:

#include <fstream>
#include <iostream>

int main() {
    std::ifstream fin("input.txt"); // 打开输入文件
    std::ofstream fout("output.txt"); // 打开输出文件
    
    int n;
    while (fin >> n) { // 从输入文件读入整数并写入到输出文件
        fout << n << " ";
    }
    
    fin.close(); // 关闭输入文件
    fout.close(); // 关闭输出文件
    return 0;
}

C++的<iomanip>头文件格式化输入输出功能

注意,std 命名空间中的常用操纵符和<iomanip> 头文件中的常用操纵符分别属于两者。这些操纵符(Manipulators)对于控制流的输入和输出非常有用。

std命名空间中常用于流的操纵符有:

endl  插入一个换行符

ends  插入一个空字符

dec  让流以十进制方式解释输入或显示输出

hex  让流以十六进制方式解释输入或显示输出

oct  让流以八进制方式解释输入或显示输出

fixed  让流以定点表示法显示数据

scientific  让流以科学表示法显示数据

下面介绍<iomanip>头文件的操纵符:

<iomanip>头文件常用于控制标准输出流的格式,例如设置输出浮点数时的位数、调整对齐方式、设置填充字符等等。【https://en.cppreference.com/w/cpp/header/iomaniphttps://cplusplus.com/reference/iomanip/  中文翻译:https://c-cpp.com/cpp/header/iomanip

例如

setw(int n):设置字段宽度为 n 字符,用于调整输出的对齐方式。示例:

cout << setw(5) << 42 << endl; //输出   42,以域宽5输出整数42,前面填充有3个空格。

setprecision(int n):设置浮点数的精度为 n 位小数。通常和fixed组合来设置输出浮点数的精度。如果用Setprecision指定的小数点后的位数大于实际数字的位数,默认使用零进行填充;如果小数点后的位数小于实际数字的位数,将按照四舍五入的规则进行四舍五入。示例:

cout << setprecision(3) << 3.14159 << endl; //输出 3.14

cout << fixed << setprecision(3) << 3.14159 << endl;   //输出 3.142

setfill(char c):将字段填充字符设置为 c。通常与 setw()一起使用。示例:

cout << setw(5) << setfill('*') << 42 << endl; //输出 ***42,前面填充有*字符。

setiosflags(flag):设置指定的 I/O 操作标志,如科学计数法、固定小数点表示法等。

resetiosflags(flag):重置(恢复到默认)指定的 I/O 操作标志。也称为清除格式化标志。

showpos:在正数前显示加号(+)。noshowpos:不显示正数前的加号。示例:

cout << showpos << 12.34 << endl; //输出+12.34,显示正数前的加号。

cout << noshowpos << 12.34 << endl; //输出12.34,不显示正数前的加号。

scientific:使用科学计数法表示法输出浮点数。不是固定小数位数的打印格式。默认情况下,在科学计数法中,小数部分将以6位精度显示。你可以使用setprecision来控制小数部分的位数。示例:

cout << scientific << 0.00123 << endl; //将会以科学计数法输出1.230e-003。

left用于左对齐输出,默认情况下,数字和文本在域内左对齐。right用于右对齐输出,即数字和文本在域内右对齐。Left和right通常与 setw()一起使用。示例:

int num = 42;

cout << setfill('#') << setw(5) << left << num << endl; // 输出 42###,即后面填充有3个#。

cout << setfill('0') << setw(5) << right << num << endl; // 输出00042,即前面填充有3个0。

setbase(n) 函数只支持十进制、八进制和十六进制,不支持二进制,默认是十进制。【setbase  设置基数,与使用dec、hex 或oct等效。】示例:

int number = 42;

cout << "Decimal: " << number << endl; //输出:Decimal: 42

cout << "Octal  : " << setbase(8) << number << endl; //输出:Octal  : 52

cout << "Hex    : " << setbase(16) << number << endl; //输出: Hex    : 2a

下面是示例程序:

#include <iostream>
#include <iomanip>  // 必须引入此头文件才能使用格式控制符

int main() {
    int i = 123;
    double d = 3.14159265359;
    std::string str = "Hello world!";

    // 设置输出浮点数精度为三位小数
    std::cout << std::fixed << std::setprecision(3);
    // 输出浮点数,如果小数位不足三位则自动补零
    std::cout << "d = " << d << std::endl;

    // 设置输出宽度为10个字符,不足则以0填充
    std::cout << std::setw(10) << std::setfill('0') << i << std::endl;

    // 设置输出宽度为20个字符,右对齐,左边用空格填充
    std::cout << std::setw(20) << std::left << str << std::endl;

    // 设置输出方式为科学计数法,保留五位小数
    std::cout << std::scientific << std::setprecision(5) << d << std::endl;

    return 0;
}

输出结果:

d = 3.142
0000000123
Hello world!
3.14159e+00

解释:

std::fixed和std::scientific用于控制输出浮点数的显示格式,分别代表固定小数点显示和科学计数法显示。

std::setprecision(n)用于设置浮点数精度,在fixed或scientific模式下,会控制小数点后保留的位数。

std::setw(n)和std::setfill(c)用于设置输出宽度和填充字符,宽度指定了输出数据的总位数,不足宽度的地方会自动用填充字符填充。必须同时使用这两个函数才能生效。

std::left和std::right用于设置输出对齐方式,左对齐和右对齐。默认是右对齐。

在 C++ 中,使用标准库提供的函数、变量和类型时,需要加上命名空间标识符 std::(其中“::”是命名空间限定符)。例如,要使用 std::cout 来输出信息。

使用 using namespace std; 在代码的开头声明引入了 std 命名空间。这样在后续的代码中就可以直接使用标准库的函数、变量和类型,而不需要再加上 std::。

引用标准名称空间,上例可改为:

#include <iostream>
#include <iomanip>  // 必须引入此头文件才能使用格式控制符
using namespace std; // 引用标准名称空间 

int main() {
    int i = 123;
    double d = 3.14159265359;
    string str = "Hello world!";

    // 设置输出浮点数精度为三位小数
    cout << fixed << setprecision(3);
    // 输出浮点数,如果小数位不足三位则自动补零
    cout << "d = " << d << endl;

    // 设置输出宽度为10个字符,不足则以0填充
    cout << setw(10) << setfill('0') << i << endl;

    // 设置输出宽度为20个字符,右对齐,左边用空格填充
    cout << setw(20) << left << str << endl;

    // 设置输出方式为科学计数法,保留五位小数
    cout << scientific << setprecision(5) << d << endl;

    return 0;
}

下面是一个比较完整的例子:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    cout << setw(5) << 42 << endl; // 输出   42,以域宽5输出整数42,前面填充有3个空格。
	cout << setw(5) << setfill('*') << 42 << endl; // 输出 ***42,前面填充有*字符。
	cout << showpos << 12.34 << endl; // 输出+12.34,显示正数前的加号。
	cout << noshowpos << 12.34 << endl; // 输出12.34,不显示正数前的加号。
    cout << setprecision(3) << 3.14159 << endl; // 输出 3.14,设置精度为3并输出浮点数。
    cout << fixed << setprecision(3) << 3.14159 << endl; // 输出 3.142,设置固定精度为3并输出浮点数。
    cout << scientific << 0.00123 << endl; // 输出1.230e-003,使用科学计数法输出浮点数。
    int num = 42;
    cout << setfill('#') << setw(5) << left << num << endl; // 输出 42###,即后面填充有3个#。
    cout << setfill('0') << setw(5) << right << num << endl; // 输出00042,即前面填充有3个0。
    
    return 0;
}

运行效果:

C和C++在输入输出方面的关系

C++是在 C 语言的基础上发展起来的,它继承了 C 语言的许多特性,如数据类型、运算符和控制结构等。然而,C++也加入了许多新的特性,如面向对象编程、继承、多态和异常处理等,使得 C++比 C 语言更加强大和灵活。
数据的输入输出是非常重要的,它允许程序与用户或者其它程序进行交互和通信。数据的输入输出通常是通过键盘,屏幕,磁盘文件或者其它设备来进行的。
在输入输出方面,C和C++都使用stdio.h头文件中定义的标准输入/输出函数来进行输入输出操作,例如printf、scanf、fscanf、sprintf、sscanf等。这些函数的使用方法在C和C++中基本相同。
但是,C++还引入了一种流式输入输出机制,即iostream,它是C++库中的一部分,定义了几个类来进行输入输出操作,例如iostream、istream、ostream、ifstream、ofstream等。这种机制可以通过运算符重载来实现更方便、更可读性更高的输入输出操作。
另外需要注意的一点是,在C中,字符串常量是通过字符数组来表示的,而在C++中,字符串常量是通过一个叫做std::string的类来表示的,它可以方便地进行各种操作。例如,在C++中,我们可以使用std::cout输出字符串常量,而在C中则需要使用printf或puts函数来输出。
总的来说,C++在输入输出方面相对于C提供了更为方便和灵活的方法,但C++也可以使用C的标准输入输出函数进行输入输出操作。
下面给出一个演示例子
输入一个双精度浮点数,保留8位小数,输出这个浮点数。
输入一行,一个双精度浮点数。样例输入
3.1415926535798932
输出一行,保留8位小数的浮点数。样例输出
3.14159265

下面是C风格的源码

#include <cstdio> //或用#include <stdio.h> 

int main() {
    double num;
    scanf("%lf", &num); //读取一个double类型的浮点数
    printf("%.8f\n", num); // 设置输出小数点后8位
    return 0;
}

下面是C++风格的源码

#include<iostream>
#include<iomanip>
using namespace std;

main(){
    double num;
    cin >> num;
    cout << fixed << setprecision(8) << num << endl;
    
    return 0;    
}


其中,fixed 和 setprecisionI/O 是操纵符(manipulators),用于控制浮点数的输出格式。


 

附录

C++语言之输入输出深入介绍https://blog.csdn.net/cnds123/article/details/126358415

c++验证用户输入合法性的示例代码https://blog.csdn.net/cnds123/article/details/130322634

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【原书名】 C++ Primer (4th Edition) 【原出版社】 Addison Wesley/Pearson 【作者】 (美)Stanley B.Lippman,Josée LaJoie,Barbara E.Moo 【译者】 李师贤 蒋爱军 梅晓勇 林瑛 【丛书名】 图灵计算机科学丛书 【出版社】 人民邮电出版社 【书号】 7-115-14554-7 【开本】 16开 【页码】 900 【出版日期】 2006-3-1 【版次】 4-1 【内容简介】 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数程序员学会了C++。本版对前一版进行了彻底的修订,内容经过了重新组织,更加入了C++ 先驱Barbara E. Moo在C++教学方面的真知灼见。既显著改善了可读性,又充分体现了C++语言的最新进展和当前的业界最佳实践。书不但新增大量教学辅助内容,用于强调重要的知识点,提醒常见的错误,推荐优秀的编程实践,给出使用提示,还包含大量来自实战的示例和习题。对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使本书成为C++初学者的最佳指南;对于高级程序员,本书也是不可或缺的参考书。本书的前言阐述了 第4版和前一版的不同之处。 【目录信息】 第1章 快速入门 1 1.1 编写简单的C++程序 2 1.2 初窥输入/输出 5 1.2.1 标准输入与输出对象 5 1.2.2 一个使用IO库的程序 5 1.3 关于注释 8 1.4 控制结构 10 1.4.1 while语句 10 1.4.2 for语句 12 1.4.3 if语句 14 1.4.4 读入未知数目的输入 15 1.5 类的简介 17 1.5.1 Sales_item类 17 1.5.2 初窥成员函数 19 1.6 C++程序 21 小结 22 术语 22 第一部分 基本语言 第2章 变量和基本类型 29 2.1 基本内置类型 30 2.1.1 整型 30 2.1.2 浮点型 32 2.2 字面值常量 34 2.3 变量 38 2.3.1 什么是变量 39 2.3.2 变量名 40 2.3.3 定义对象 42 2.3.4 变量初始化规则 44 2.3.5 声明和定义 45 2.3.6 名字的作用域 46 2.3.7 在变量使用处定义变量 48 2.4 const限定符 49 2.5 引用 50 2.6 typedef名字 53 2.7 枚举 53 2.8 类类型 54 2.9 编写自己的头文件 57 2.9.1 设计自己的头文件 58 2.9.2 预处理器的简单介绍 60 小结 62 术语 62 第3章 标准库类型 67 3.1 命名空间的using声明 68 3.2 标准库string类型 70 3.2.1 string对象的定义和初始化 70 3.2.2 String对象的读写 71 3.2.3 string对象的操作 72 3.2.4 string对象字符的处理 76 3.3 标准库vector类型 78 3.3.1 vector对象的定义和初始化 79 3.3.2 vector对象的操作 81 3.4 迭代器简介 83 3.5 标准库bitset类型 88 3.5.1 bitset对象的定义和初始化 88 3.5.2 bitset对象上的操作 90 小结 92 术语 92 第4章 数组和指针 95 4.1 数组 96 4.1.1 数组的定义和初始化 96 4.1.2 数组操作 99 4.2 指针的引入 100 4.2.1 什么是指针 100 4.2.2 指针的定义和初始化 101 4.2.3 指针操作 104 4.2.4 使用指针访问数组元素 106 4.2.5 指针和const限定符 110 4.3 C风格字符串 113 4.3.1 创建动态数组 117 4.3.2 新旧代码的兼容 120 4.4 多维数组 122 小结 124 术语 125 第5章 表达式 127 5.1 算术操作符 129 5.2 关系操作符和逻辑操作符 131 5.3 位操作符 134 5.3.1 bitset对象或整型值的使用 135 5.3.2 将移位操作符用于IO 137 5.4 赋值操作符 137 5.4.1 赋值操作的右结合性 138 5.4.2 赋值操作具有低优先级 138 5.4.3 复合赋值操作符 139 5.5 自增和自减操作符 140 5.6 箭头操作符 142 5.7 条件操作符 143 5.8 sizeof操作符 144 5.9 逗号操作符 145 5.10 复合表达式的求值 145 5.10.1 优先级 145 5.10.2 结合性 146 5.10.3 求值顺序 148 5.11 new和delete表达式 150 5.12 类型转换 154 5.12.1 何时发生隐式类型转换 154 5.12.2 算术转换 155 5.12.3 其他隐式转换 156 5.12.4 显式转换 158 5.12.5 何时需要强制类型转换 158 5.12.6 命名的强制类型转换 158 5.12.7 旧式强制类型转换 160 小结 161 术语 162 第6章 语句 165 6.1 简单语句 166 6.2 声明语句 167 6.3 复合语句(块) 167 6.4 语句作用域 168 6.5 if语句 169 6.6 switch语句 172 6.6.1 使用switch 173 6.6.2 switch的控制流 173 6.6.3 default标号 175 6.6.4 switch表达式与case标号 176 6.6.5 switch内部的变量定义 176 6.7 while语句 177 6.8 for循环语句 179 6.8.1 省略for语句头的某些部分 180 6.8.2 for语句头的多个定义 181 6.9 do while语句 182 6.10 break语句 183 6.11 continue语句 184 6.12 goto语句 185 6.13 try块和异常处理 186 6.13.1 throw表达式 186 6.13.2 try块 187 6.13.3 标准异常 189 6.14 使用预处理器进行调试 190 小结 192 术语 192 第7章 函数 195 7.1 函数的定义 196 7.1.1 函数返回类型 197 7.1.2 函数形参表 198 7.2 参数传递 199 7.2.1 非引用形参 199 7.2.2 引用形参 201 7.2.3 vector和其他容器类型的形参 206 7.2.4 数组形参 206 7.2.5 传递给函数的数组的处理 209 7.2.6 main:处理命令行选项 210 7.2.7 含有可变形参的函数 211 7.3 return语句 211 7.3.1 没有返回值的函数 212 7.3.2 具有返回值的函数 212 7.3.3 递归 216 7.4 函数声明 217 7.5 局部对象 220 7.5.1 自动对象 220 7.5.2 静态局部对象 220 7.6 内联函数 221 7.7 类的成员函数 222 7.7.1 定义成员函数的函数体 223 7.7.2 在类外定义成员函数 225 7.7.3 编写Sales_item类的构造 函数 225 7.7.4 类代码文件的组织 227 7.8 重载函数 228 7.8.1 重载与作用域 230 7.8.2 函数匹配与实参转换 231 7.8.3 重载确定的三个步骤 232 7.8.4 实参类型转换 234 7.9 指向函数的指针 237 小结 239 术语 240 第8章 标准IO库 243 8.1 面向对象的标准库 244 8.2 条件状态 247 8.3 输出缓冲区的管理 249 8.4 文件的输入和输出 251 8.4.1 文件流对象的使用 251 8.4.2 文件模式 254 8.4.3 一个打开并检查输入文件的 程序 256 8.5 字符串流 257 小结 259 术语 259 第二部分 容器和算 第9章 顺序容器 263 9.1 顺序容器的定义 264 9.1.1 容器元素的初始化 265 9.1.2 容器内元素的类型约束 267 9.2 迭代器和迭代器范围 268 9.2.1 迭代器范围 270 9.2.2 使迭代器失效的容器操作 271 9.3 顺序容器的操作 272 9.3.1 容器定义的类型别名 272 9.3.2 begin和end成员 273 9.3.3 在顺序容器添加元素 273 9.3.4 关系操作符 277 9.3.5 容器大小的操作 278 9.3.6 访问元素 279 9.3.7 删除元素 280 9.3.8 赋值与swap 282 9.4 vector容器的自增长 284 9.5 容器的选用 287 9.6 再谈string类型 289 9.6.1 构造string对象的其他方 290 9.6.2 修改string对象的其他方 292 9.6.3 只适用于string类型的操作 293 9.6.4 string类型的查找操作 295 9.6.5 string对象的比较 298 9.7 容器适配器 300 9.7.1 栈适配器 301 9.7.2 队列和优先级队列 302 小结 303 术语 303 第10章 关联容器 305 10.1 引言:pair类型 306 10.2 关联容器 308 10.3 map类型 309 10.3.1 map对象的定义 309 10.3.2 map定义的类型 310 10.3.3 给map添加元素 311 10.3.4 使用下标访问map对象 311 10.3.5 map::insert的使用 313 10.3.6 查找并读取map的元素 315 10.3.7 从map对象删除元素 316 10.3.8 map对象的迭代遍历 316 10.3.9 “单词转换”map对象 317 10.4 set类型 319 10.4.1 set容器的定义和使用 319 10.4.2 创建“单词排除”集 321 10.5 multimap和multiset类型 322 10.5.1 元素的添加和删除 322 10.5.2 在multimap和multiset 查找元素 323 10.6 容器的综合应用:文本查询程序 325 10.6.1 查询程序的设计 326 10.6.2 TextQuery类 327 10.6.3 TextQuery类的使用 328 10.6.4 编写成员函数 330 小结 332 术语 332 第11章 泛型算 335 11.1 概述 336 11.2 初窥算 339 11.2.1 只读算 339 11.2.2 写容器元素的算 341 11.2.3 对容器元素重新排序的算 343 11.3 再谈迭代器 347 11.3.1 插入迭代器 348 11.3.2 iostream迭代器 349 11.3.3 反向迭代器 353 11.3.4 const迭代器 355 11.3.5 五种迭代器 356 11.4 泛型算的结构 358 11.4.1 算的形参模式 359 11.4.2 算的命名规范 359 11.5 容器特有的算 361 小结 362 术语 363 第三部分 类和数据抽象 第12章 类 367 12.1 类的定义和声明 368 12.1.1 类定义:扼要重述 368 12.1.2 数据抽象和封装 369 12.1.3 关于类定义的更多内容 372 12.1.4 类声明与类定义 374 12.1.5 类对象 375 12.2 隐含的this指针 376 12.3 类作用域 380 类作用域的名字查找 382 12.4 构造函数 385 12.4.1 构造函数初始化式 387 12.4.2 默认实参与构造函数 391 12.4.3 默认构造函数 392 12.4.4 隐式类类型转换 393 12.4.5 类成员的显式初始化 396 12.5 友元 396 12.6 static类成员 398 12.6.1 static成员函数 400 12.6.2 static数据成员 400 小结 403 术语 403 第13章 复制控制 405 13.1 复制构造函数 406 13.1.1 合成的复制构造函数 409 13.1.2 定义自己的复制构造函数 409 13.1.3 禁止复制 410 13.2 赋值操作符 411 13.3 析构函数 412 13.4 消息处理示例 415 13.5 管理指针成员 419 13.5.1 定义智能指针类 421 13.5.2 定义值型类 425 小结 427 术语 427 第14章 重载操作符与转换 429 14.1 重载操作符的定义 430 14.2 输入和输出操作符 435 14.2.1 输出操作符<>的重载 437 14.3 算术操作符和关系操作符 439 14.3.1 相等操作符 440 14.3.2 关系操作符 441 14.4 赋值操作符 441 14.5 下标操作符 442 14.6 成员访问操作符 443 14.7 自增操作符和自减操作符 446 14.8 调用操作符和函数对象 449 14.8.1 将函数对象用于标准库算 450 14.8.2 标准库定义的函数对象 451 14.8.3 函数对象的函数适配器 453 14.9 转换与类类型 454 14.9.1 转换为什么有用 454 14.9.2 转换操作符 455 14.9.3 实参匹配和转换 458 14.9.4 重载确定和类的实参 461 14.9.5 重载、转换和操作符 464 小结 466 术语 467 第四部分 面向对象编程与泛型编程 第15章 面向对象编程 471 15.1 面向对象编程:概述 472 15.2 定义基类和派生类 473 15.2.1 定义基类 474 15.2.2 protected成员 475 15.2.3 派生类 476 15.2.4 virtual与其他成员函数 479 15.2.5 公用、私有和受保护的继承 482 15.2.6 友元关系与继承 486 15.2.7 继承与静态成员 486 15.3 转换与继承 487 15.3.1 派生类到基类的转换 487 15.3.2 基类到派生类的转换 489 15.4 构造函数和复制控制 490 15.4.1 基类构造函数和复制控制 490 15.4.2 派生类构造函数 490 15.4.3 复制控制和继承 494 15.4.4 虚析构函数 495 15.4.5 构造函数和析构函数的虚函数 497 15.5 继承情况下的类作用域 497 15.5.1 名字查找在编译时发生 498 15.5.2 名字冲突与继承 498 15.5.3 作用域与成员函数 499 15.5.4 虚函数与作用域 500 15.6 纯虚函数 502 15.7 容器与继承 503 15.8 句柄类与继承 504 15.8.1 指针型句柄 505 15.8.2 复制未知类型 507 15.8.3 句柄的使用 508 15.9 再谈文本查询示例 511 15.9.1 面向对象的解决方案 513 15.9.2 值型句柄 514 15.9.3 Query_base类 515 15.9.4 Query句柄类 516 15.9.5 派生类 518 15.9.6 eval函数 520 小结 522 术语 523 第16章 模板与泛型编程 525 16.1 模板定义 526 16.1.1 定义函数模板 526 16.1.2 定义类模板 528 16.1.3 模板形参 529 16.1.4 模板类型形参 531 16.1.5 非类型模板形参 533 16.1.6 编写泛型程序 534 16.2 实例化 535 16.2.1 模板实参推断 537 16.2.2 函数模板的显式实参 540 16.3 模板编译模型 542 16.4 类模板成员 545 16.4.1 类模板成员函数 548 16.4.2 非类型形参的模板实参 551 16.4.3 类模板的友元声明 552 16.4.4 Queue和QueueItem的友元 声明 554 16.4.5 成员模板 556 16.4.6 完整的Queue类 558 16.4.7 类模板的static成员 559 16.5 一个泛型句柄类 560 16.5.1 定义句柄类 561 16.5.2 使用句柄 562 16.6 模板特化 564 16.6.1 函数模板的特化 565 16.6.2 类模板的特化 567 16.6.3 特化成员而不特化类 569 16.6.4 类模板的部分特化 570 16.7 重载与函数模板 570 小结 573 术语 574 第五部分 高级主题 第17章 用于大型程序的工具 579 17.1 异常处理 580 17.1.1 抛出类类型的异常 581 17.1.2 栈展开 582 17.1.3 捕获异常 583 17.1.4 重新抛出 585 17.1.5 捕获所有异常的处理代码 586 17.1.6 函数测试块与构造函数 586 17.1.7 异常类层次 587 17.1.8 自动资源释放 589 17.1.9 auto_ptr类 591 17.1.10 异常说明 595 17.1.11 函数指针的异常说明 598 17.2 命名空间 599 17.2.1 命名空间的定义 599 17.2.2 嵌套命名空间 603 17.2.3 未命名的命名空间 604 17.2.4 命名空间成员的使用 606 17.2.5 类、命名空间和作用域 609 17.2.6 重载与命名空间 612 17.2.7 命名空间与模板 614 17.3 多重继承与虚继承 614 17.3.1 多重继承 615 17.3.2 转换与多个基类 617 17.3.3 多重继承派生类的复制控制 619 17.3.4 多重继承下的类作用域 620 17.3.5 虚继承 622 17.3.6 虚基类的声明 624 17.3.7 特殊的初始化语义 625 小结 628 术语 628 第18章 特殊工具与技术 631 18.1 优化内存分配 632 18.1.1 C++的内存分配 632 18.1.2 allocator类 633 18.1.3 operator new函数和 operator delete函数 636 18.1.4 定位new表达式 638 18.1.5 显式析构函数的调用 639 18.1.6 类特定的new和delete 639 18.1.7 一个内存分配器基类 641 18.2 运行时类型识别 646 18.2.1 dynamic_cast操作符 647 18.2.2 typeid操作符 649 18.2.3 RTTI的使用 650 18.2.4 type_info类 652 18.3 类成员的指针 653 18.3.1 声明成员指针 653 18.3.2 使用类成员的指针 655 18.4 嵌套类 658 18.4.1 嵌套类的实现 658 18.4.2 嵌套类作用域的名字查找 661 18.5 联合:节省空间的类 662 18.6 局部类 665 18.7 固有的不可移植的特征 666 18.7.1 位域 666 18.7.2 volatile限定符 668 18.7.3 链接指示:extern "C" 669 小结 672 术语 673 附录 标准库 675 索引 703

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值