C ++如何将文件中的字符串读入std :: string变量,文件是FILE的指针

时间:2014-12-21 17:33:55

标签: c++ string c++11

我想从文件输入中读取字符串到std::string变量 我声明了一个打开文件的FILE指针:

  

FILE *f = fopen("IN.txt","r");

然后,我使用fscanf()函数阅读:

  

std::string tempStr;
  fscanf(f,"%s",tempStr); //Compile Error
  //fscanf(f,"%s",&tempStr);//Runtime Error

所以,我有两个问题:
1.是否可以解决上述问题(仍使用FILE *ffscanf()功能)?
我是C程序员,是C ++的新手。如何用不同的方式解决这个问题?

这是我的代码:

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

int main()
{
    int n;
    string cities[100];
    FILE * f = fopen("IN.txt", "r");
    fscanf(f,"%d",&n);
    for (int i=0; i<n;i++)
    {
        string tempStr;
        fscanf(f,"%s",tempStr);
        cities[i] = tempStr;
    }
    return 0;
}

输入文件(第一行是行数):

8
Vancouver
Yellowknife
Edmonton
Calgary
Winnipeg
Toronto
Montreal
Halifax

3 个答案:

答案 0 :(得分:2)

如果您想直接阅读std::string,可以使用FILE*但是您无法使用fscanf():这种舞蹈的方式是创建一个流缓冲区将FILE*呈现为std::istream

可以使用的内容
#include <iostream>
#include <stdio.h>
class cfilebuf
    : public std::streambuf {
    FILE* file;
    char  c;
    int underflow() {
        int value = fgetc(this->file);
        if (value != EOF) {
            c = value;
            this->setg(&c, &c, &c + 1);
            return c;
        }
        return std::char_traits<char>::eof();
    }
public:
    cfilebuf(FILE* file): file(file) {}
    // to own or not to own? ~cfilebuf() { fclose(this->file; }
};

int main() {
    cfilebuf     sbuf(stdin);
    std::istream in(&sbuf);
    std::string  s;
    if (in >> s) {
         std::cout << "read '" << s << "'\n";
    }
}

请注意,此流缓冲区适用于您使用FILE*std::istream*不断切换的设置。如果你合理地只使用std::istream接口到FILE*,你宁可创建一个读取整个缓冲区的流缓冲区:效率更高。您也可能希望将流和流缓冲区的数据包构造成一个对象:

class icfilestream
    : private virtual cfilebuf
    , public std::istream {
public:
    icfilestream(FILE* file)
        : cfilebuf(file)
        , std::ios(static_cast<std::streambuf*>(this))
        , std::istream(static_cast<std::streambuf*>(this)) {
    }
};

答案 1 :(得分:0)

#include <fstream>
#include <string>
using namespace std;

int main()
{
    int n;
    string cities[100];
    ifstream f("IN.txt");
    f >> n;
    for (int i=0; i<n;i++)
    {
        f >> cities[i];
    }
    return 0;
}

更好的是,std::vector<string>使用cities(此修改留给读者练习。)

答案 2 :(得分:0)

您应该使用流类,std::getline或直接读入字符串。但是,如果你真的想要,在你的情况下可以做类似的事情:

fscanf(f,"%s",tempStr); // tempStr is declared as char tempStr[N]
cities[i] = std::string(tempStr); // convert to a string

请注意,您最初在char缓冲区(超级不安全的btw)中阅读,然后将其转换为std::string。但是,当你只是做

时,我认为没有理由使用这段代码
fin >> cities[i] 

在循环中,其中finstd::ifstream