C语言中scanf、gets、fgets,C++中cin、getline读取字符串的效率比较

2023-05-16

转自:https://blog.csdn.net/richenyunqi/article/details/89203826
可以使用C语言中scanf、gets、fgets,C++中cin、getline函数读取字符串,当字符串字符数量非常大时,这些函数的效率究竟是如何的呢?本博客主要解决这一问题。
准备测试数据
我们先在桌面新建一个名为test的文件夹,作为本次实验的文件夹。我们希望向该文件夹下的input.txt文件(这个文件程序会自动生成)中写入5000个字符串,每个字符串为10000个0字符,字符串间用换行符分隔开,共计5000万个字符,以此作为输入数据, 程序如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    ofstream out("C:/Users/Administrator/Desktop/test/input.txt");//文件路径可按你自己的想法替换
    for(int i=0;i<5000;++i){
        for(int j=0;j<10000;++j){
            out<<"0";
        }
        out<<endl;
    }
    out.close();
    puts("successful");//控制台输出successful时,表示文件数据写入完毕
    return 0;
}

读取数据
共对C语言中scanf、gets、fgets,C++中cin、getline这5个函数进行比较,我们可以让这5个函数分别读取1000万个0字符。程序如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
char input[100005];
string str;

clock_t s= clock();//读取开始时间
for(int i=0;i<1000;++i)
    scanf("%s",input);
clock_t e= clock();//读取完毕时间
printf("scanf:%.0fms\n",(double)(e-s)/CLOCKS_PER_SEC*1000);//输出整个读取过程花费时间,单位:毫秒

s= clock();//读取开始时间
for(int i=0;i<1000;++i)
    gets(input);

e= clock();//读取完毕时间
printf(“gets:%.0fms\n”,(double)(e-s)/CLOCKS_PER_SEC*1000);//输出整个读取过程花费时间,单位:毫秒

s= clock();//读取开始时间
for(int i=0;i<1000;++i)
    fgets(input,10005,stdin);
e= clock();//读取完毕时间
printf("fgets:%.0fms\n",(double)(e-s)/CLOCKS_PER_SEC*1000);//输出整个读取过程花费时间
,单位:毫秒*/

s= clock();//读取开始时间
for(int i=0;i<1000;++i)
    cin>>str;
e= clock();//读取完毕时间
printf("cin:%.0fms\n",(double)(e-s)/CLOCKS_PER_SEC*1000);/*输出整个读取过程花费时间
,单位:毫秒*/

s= clock();//读取开始时间
for(int i=0;i<1000;++i)
    getline(cin,str);
e= clock();//读取完毕时间
printf("getline:%.0fms\n",(double)(e-s)/CLOCKS_PER_SEC*1000);/*输出整个读取过程花费时间
,单位:毫秒*/
return 0;
}

编译运行后会生成一个exe可执行文件,找到这个exe文件并复制粘贴到test文件夹下。并重命名为test.exe
进行比较
在test文件夹下新建一个compare.txt文件,并向其中写入以下程序:

test < input.txt > output.txt
pause

保存并关闭文件后,将compare.txt的后缀名txt更改为bat。
经过以上操作后,test文件夹下应该有3个文件:

input.txt:测试数据
test.exe:测试程序
compare.bat:执行脚本
此时双击compare.bat脚本,会跳出一个dos窗口,等待一段时间,当dos窗口输出请按任意键继续. . .的字样时,关闭dos窗口,会发现test文件夹下新生成了一个output.txt文件,打开该文件,就可以看到各个函数读取数据所用时间。
我执行时output.txt文件内容如下:

scanf:960ms
gets:72ms
fgets:76ms
cin:2275ms
getline:2189ms

结论
按照所用时间从小到大进行排序,得到的结果如下:
在这里插入图片描述
我们可以发现gets和fgets函数读取字符串的速度是最快的,读取时间约为scanf函数的1/13,约为getline和cin的1/30,由于gets函数由于不安全已被c11标准废弃,在以后读取字符串时,如果字符串很长,应尽可能使用fgets函数。
另外,scanf函数的读取效率约为getline和cin的1/2,getline比cin稍快。

那么为什么会出现这样的情况呢?
以fgets函数和scanf函数为例,由于fgets只负责读取字符串,而scanf函数还可以读取其他如int、double类型的数据,所以scanf函数就多了确定读取的数据是何种类型的步骤,因而花费了更多的时间。
而getline和cin函数只能向string类型中读入数据,由于string类型是在堆上分配的,在读取数据的时候需要不断从堆上申请动态分配内存,不如char数组直接提前分配好了所有内存来得更为简便。此外在向string类型读入数据的时候,还需要调用string类型的构造函数,初始化包括begin()、end()、size()等类内数据成员和成员函数,这也花费了很多时间。所以string类型比char数组提供了许多使用更为简便的函数和成员,但也要为此承担时间上的代价。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言中scanf、gets、fgets,C++中cin、getline读取字符串的效率比较 的相关文章

  • Scanf 漏行

    我编写了一个测试程序 它应该接受 3x3 字符矩阵并输出输入的矩阵 但是 我必须输入 4 行才能让程序生成相应的矩阵 我已经查找了 scanf 函数的问题 但我尝试过的解决方案似乎都不起作用 你能帮我解决这个问题吗 My code incl
  • scanf() 格式字符串中尾随空格有何影响?

    有什么区别scanf d and scanf d 在此代码中 区别在于格式字符串中的尾随空白 include
  • strstr 不工作

    如果我输入 test 为什么这段特定的代码在 strstr 上返回 false char input 100 int main fgets input 100 stdin printf s input if strstr test mess
  • 从十六进制 istream 中读取双精度值

    Given double foo我可以使用十六进制格式字符串分配它sscanf像这样 sscanf 0XD lg foo 但我似乎无法得到istringstream以同样的方式行事 所有这些都只需写入 0 即可foo istringstre
  • c getline 跳过空行

    while getline line line size f 1 I m using this function to read line line But i want to know when i m reading a blank l
  • 使用 sscanf 迭代

    我对 sscanf 函数了解不多 但我想做的是迭代一行整数 给定变量 char lineOfInts 我已将其作为注册用户输入的行 我能够很好地获得输入 但是当我尝试使用 sscanf 时 我想迭代每个 int 我知道如果我知道之前会有多少
  • 为什么 getline() 函数不起作用,除非我在函数 chamodifier 中调用它两次[重复]

    这个问题在这里已经有答案了 怎么了如果我在字符修饰符函数中仅使用一次 get line 函数 编译器将忽略它 除非我调用该函数两次 为什么我不能只使用一次 我尝试使用其他方法 它有效 但我想了解这个 我现在只是随机编写一些内容 这样添加更多
  • do while 循环不能有两个 cin 语句吗?

    我只是遵循一个关于 do while 循环的简单 C 教程 我似乎已经完全复制了教程中编写的内容 但我没有得到相同的结果 这是我的代码 int main int c 0 int i 0 int str do cout lt lt Enter
  • 如何确定 fgets 是否在读取所有字母之前停止?

    我做了这样的事情 char buf 100 int n 0 char save 100 100 while fgets buf 100 file NULL strcpy save n buf printf s buf n 我开了一个FILE
  • C 中 scanf 函数的格式说明符中 %c 规范之前的空格

    当我之间不包含空格时 d and c格式字符串中的规范scanf 在以下程序中运行函数 并在运行时输入 4 h 则输出为 Integer 4 and Character 究竟如何可变 c 在这种情况下接受输入 如果我在之间包含空格 会有什么
  • 如何在先前输入后使用 C++ 中的“获取”函数?

    我尝试输入数据gets 函数 但每当程序执行到留置权时gets 它会忽略它 当我使用gets 没有之前的数据输入 它可以正常运行 但是当我在输入数据后使用它时 就会出现问题 这是在先前的数据输入之后使用它的代码 因此在执行中我无法将数据输入
  • getline 跳过第一个输入字符 c++ [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 所以我制作
  • fseek() 按行而不是字节?

    我有一个可以逐行解析大文件的脚本 当它遇到无法处理的错误时 它会停止 通知我们解析的最后一行 这真的是寻找文件中特定行的最佳 唯一方法吗 fseek 在我的情况下不可用
  • 如何读取长度未知的输入字符串?

    如果我不知道这个词有多长 我就无法写char m 6 这个词的长度可能有十到二十长 我该如何使用scanf从键盘获取输入 include
  • 无法从 cin.get() 获取 char

    我正在做一些关于 C 的初学者练习 这让我很困惑 我可以输入数字 但之后无法选择输入字符 并且会跳到最后一行 我知道我可以使用 cin gt gt 符号 但我想知道为什么这不起作用 include
  • Java 中的 sscanf 等效项[重复]

    这个问题在这里已经有答案了 可能的重复 用于使用已知模式解析字符串中的值的 sscanf 的 Java 等效项是什么 https stackoverflow com questions 8430022 what is the java eq
  • scanf() 不等待用户输入[重复]

    这个问题在这里已经有答案了 我正在使用 c 中的双向链表来制作树 我在该函数中使用递归调用 但不知何故它不起作用 我的代码是 struct node int data struct node right struct node left s
  • 漏洞利用开发 - GETS 和 Shellcode

    试图了解更多有关利用开发和构建 shellcode 的信息 但遇到了一个我不明白背后原因的问题 为什么我无法运行 execve bin sh 等 shellcode 并生成可以与之交互的 shell 另一方面 我可以创建一个反向 bind
  • scanf %u 负数?

    我努力了scanf u number 我输入了负数 问题是当我printf d number 我得到负数 我认为这会阻止我读取负数 是scanf d number and scanf u number 真的是同一件事吗 或者只是为了可读性
  • Python 中 Matlab 'fscanf' 的等价物是什么?

    Matlab函数fscanf 似乎很强大 python 或numpy 中是否有相同的等效项 具体来说 我想从文件中读取矩阵 但我不想迭代每一行来读取矩阵 类似的东西 来自 matlab 用于读取 2D 1000x1000 矩阵 matrix

随机推荐