Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我的C+版本+;采用文件*(由wfopen()创建)而不是流的非成员getline()太慢 在C++中,可以使用非成员GETILLY()在循环中这样的流: #include <string> #include <fstream> #include <cstdlib> using namespace std; int main() { ifstream in("file.txt"); if (!in) { return EXIT_FAILURE; } for (string line; getline(in, line); ) { // Do stuff with each line } } #包括 #包括 #包括 使用名称空间std; int main(){ ifstream in(“file.txt”); 如果(!in){ 返回退出失败; } for(字符串行;getline(in,line);){ //每行都做些事情 } }_C++ - Fatal编程技术网

我的C+版本+;采用文件*(由wfopen()创建)而不是流的非成员getline()太慢 在C++中,可以使用非成员GETILLY()在循环中这样的流: #include <string> #include <fstream> #include <cstdlib> using namespace std; int main() { ifstream in("file.txt"); if (!in) { return EXIT_FAILURE; } for (string line; getline(in, line); ) { // Do stuff with each line } } #包括 #包括 #包括 使用名称空间std; int main(){ ifstream in(“file.txt”); 如果(!in){ 返回退出失败; } for(字符串行;getline(in,line);){ //每行都做些事情 } }

我的C+版本+;采用文件*(由wfopen()创建)而不是流的非成员getline()太慢 在C++中,可以使用非成员GETILLY()在循环中这样的流: #include <string> #include <fstream> #include <cstdlib> using namespace std; int main() { ifstream in("file.txt"); if (!in) { return EXIT_FAILURE; } for (string line; getline(in, line); ) { // Do stuff with each line } } #包括 #包括 #包括 使用名称空间std; int main(){ ifstream in(“file.txt”); 如果(!in){ 返回退出失败; } for(字符串行;getline(in,line);){ //每行都做些事情 } },c++,C++,但是,我想用一个由wfuopen(“FILE.txt”,“r”)创建的文件*来实现这一点,所以我创建了一个: #include <cstdio> #include <string> #include <cstdlib> #include <cwchar> using namespace std; bool getline(FILE* const in, string& s) { int c = fgetc(in); if

但是,我想用一个由wfuopen(“FILE.txt”,“r”)创建的文件*来实现这一点,所以我创建了一个:

#include <cstdio>
#include <string>
#include <cstdlib>
#include <cwchar>
using namespace std;

bool getline(FILE* const in, string& s) {
    int c = fgetc(in);
    if (c == EOF) {
        return false;
    }
    s.clear();
    while (c != EOF && c != 10 && c != 13) {
        s += c;
        c = fgetc(in);
    }
    return true;
}

int main() {
    FILE* const in = _wfopen(L"file.txt", L"r");
    if (!in) {
        return EXIT_FAILURE;
    }
    for (string line; getline(in, line); ) {
        // Do stuff with the line
    }
    if (in) {
        fclose(in);
    }
}
#包括
#包括
#包括
#包括
使用名称空间std;
bool getline(文件*const-in,字符串&s){
int c=fgetc(in);
如果(c==EOF){
返回false;
}
s、 清除();
而(c!=EOF&&c!=10&&c!=13){
s+=c;
c=fgetc(英寸);
}
返回true;
}
int main(){
FILE*const in=wfopen(L“FILE.txt”,L“r”);
如果(!in){
返回退出失败;
}
for(字符串行;getline(in,line);){
//用绳子做点什么
}
如果(在){
fclose(in);
}
}
它像我想要的那样处理换行符,像我想要的那样在循环中工作。它太慢了,因为我一次读取一个字符,一次在字符串中插入一个字符。例如,处理一个12MB的文件需要6秒钟,而原始getline实际上是立即处理的。对于一个小文件来说,这不是什么大问题,但对于一个2GB文件来说,这将是一个问题

我希望它能像C++的getline()一样快,但我认为如果不重新设计它,我无法使它更快

那么,我应该如何重新设计它,使其更有效

我知道我应该将块放在缓冲区中(例如向量,需要时调整大小),直到我在其中找到一个换行符或换行符对并将范围附加到字符串。然而,我并没有真正想象如何使它像我的逐字符版本一样工作,特别是如果我读入太多,并且必须将换行符或换行符对后的数据放回流中,以便在下一次迭代中使用

现在,VC++有一个接受文件*的wifstream,STLPort可能也有一个。但是,我只使用了mingw4.4.1。(我不想使用STLPort,因为使用Mingw进行构建是一件痛苦的事情。)

我需要使用文件*的原因是因为wfopen()返回的是文件*。我需要使用_wfopen(),因为它支持我将从windows函数CommandLineToArgvW(CommandLineW(),&argc)返回的wchar\u t**数组中获取的wchar\u t*路径。ifstream不会走很宽的路


谢谢

您的
std::string
实现可能无法以高效的方式逐个追加多个字符来增加字符串。要尝试的一件事可能是在缓冲区已满时使用
std::string::reserve()
将字符串容量加倍

编辑:
顺便说一句,我应该补充一点,如果您希望在文本模式下打开
文件*
,您不需要同时检查
\n
\r
,因为适合平台的换行符转换是由文本模式下的C stdio函数自动执行的。(但是,如果您打算读取在其他平台上创建的文件(例如,在Unix上读取Windows文件),则需要检查各种类型的行尾。)

您的
std::string
实现可能不会以一个接一个高效追加多个字符的方式增长字符串。要尝试的一件事可能是在缓冲区已满时使用
std::string::reserve()
将字符串容量加倍

编辑: 顺便说一句,我应该补充一点,如果您希望在文本模式下打开
文件*
,您不需要同时检查
\n
\r
,因为适合平台的换行符转换是由文本模式下的C stdio函数自动执行的。(如果你打算读取其他平台上创建的文件(例如,在UNIX上读取Windows文件),那么你需要检查各种类型的行结束。)

< P>如果你在C++中编程,你应该使用C++ I/O设备。话虽如此

首先,通过检查10和13来检查换行符。您应该以文本模式打开文件,并改为检查
'\n'
。此方法是可移植的,并且适用于不同的行结束约定以及非ASCII系统

假设您必须使用本机C
文件*
,我会这样做:

#include <cstdio>
#include <cstring>
#include <string>

bool cgetline(FILE* const in, std::string &s)
{
    char buf[BUFSIZ+1] = {0};
    s.clear();
    while (fgets(buf, sizeof buf, in) != NULL) {
        char *end = strchr(buf, '\n');
        if (end == NULL) {
            /* We didn't see a newline at the end of the line,
               if we hit the end of file, then the last line wasn't terminated
               with a newline character.  Return it anyway. */
            if (feof(in)) {
                s.append(buf, strlen(buf));
                return true;
            } else {
                s.append(buf, sizeof buf - 1);
            }
        } else {
            s.append(buf, end - buf);
            return true;
        }
    }
    return false;
}
#包括
#包括
#包括
bool cgetline(文件*const-in,std::string&s)
{
char buf[BUFSIZ+1]={0};
s、 清除();
while(fgets(buf,sizeof buf,in)!=NULL){
char*end=strchr(buf,'\n');
if(end==NULL){
/*我们在这一行的末尾没有看到新行,
如果我们到达文件的末尾,那么最后一行就没有终止
使用换行符。仍然返回它*/
if(feof(in)){
s、 附加(buf,strlen(buf));
返回true;
}否则{
s、 追加(buf,sizeof buf-1);
}
}否则{
s、 追加(buf,end-buf);
返回true;
}
}
返回false;
}
当文件的最后一行没有以换行符结尾时,要确保程序执行正确的操作,这是一个复杂的问题

从字符读取文件并附加到字符串可能是为什么您的版本慢。

< P>如果您在C++中编程,您应该使用C++ I/O设备。话虽如此

首先,通过检查10和13来检查换行符。您应该以文本模式打开文件,并改为检查
'\n'
。此方法是可移植的,并且适用于不同的行结束约定以及非ASCII系统

假设您必须使用本机C
文件*
,我会这样做