Programing

전체 ASCII 파일을 C ++ std :: string [duplicate]로 읽기

crosscheck 2020. 10. 4. 10:28
반응형

전체 ASCII 파일을 C ++ std :: string [duplicate]로 읽기


전체 파일을 메모리로 읽어서 C ++에 넣어야 std::string합니다.

으로 읽으면 char[]대답은 매우 간단합니다.

std::ifstream t;
int length;
t.open("file.txt");      // open input file
t.seekg(0, std::ios::end);    // go to the end
length = t.tellg();           // report location (this is the length)
t.seekg(0, std::ios::beg);    // go back to the beginning
buffer = new char[length];    // allocate memory for a buffer of appropriate dimension
t.read(buffer, length);       // read the whole file into the buffer
t.close();                    // close file handle

// ... Do stuff with buffer here ...

지금, 나는 똑같은 일을하고 싶어하지만, 사용하는 std::string대신의를 char[]. 루프를 피하고 싶습니다. 즉, 다음을 원하지 않습니다 .

std::ifstream t;
t.open("file.txt");
std::string buffer;
std::string line;
while(t){
std::getline(t, line);
// ... Append line to buffer and go on
}
t.close()

어떤 아이디어?


업데이트 : 이 방법은 STL 관용구를 잘 따르지만 실제로는 놀랍게도 비효율적입니다! 대용량 파일에는이 작업을 수행하지 마십시오. (참조 : http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

파일에서 streambuf 반복자를 만들고이를 사용하여 문자열을 초기화 할 수 있습니다.

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

t.open("file.txt", "r")구문을 어디서 얻었는지 확실하지 않습니다 . 내가 아는 한 그것은 방법이 아닙니다 std::ifstream. C와 혼동 한 것 같습니다 fopen.

편집 : 또한 문자열 생성자에 대한 첫 번째 인수 주위의 추가 괄호에 유의하십시오. 이것들은 필수적 입니다. 그들은 " 가장 성가신 구문 분석 " 으로 알려진 문제를 방지합니다 .이 경우 실제로는 보통처럼 컴파일 오류가 발생하지는 않지만 흥미로운 (읽기 : 잘못된) 결과를 제공합니다.

주석에서 KeithB의 요점에 따라 모든 메모리를 미리 할당하는 방법이 있습니다 (문자열 클래스의 자동 재 할당에 의존하는 대신).

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str;

t.seekg(0, std::ios::end);   
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);

str.assign((std::istreambuf_iterator<char>(t)),
            std::istreambuf_iterator<char>());

There are a couple of possibilities. One I like uses a stringstream as a go-between:

std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();

Now the contents of "file.txt" are available in a string as buffer.str().

Another possibility (though I certainly don't like it as well) is much more like your original:

std::ifstream t("file.txt");
t.seekg(0, std::ios::end);
size_t size = t.tellg();
std::string buffer(size, ' ');
t.seekg(0);
t.read(&buffer[0], size); 

Officially, this isn't required to work under the C++98 or 03 standard (string isn't required to store data contiguously) but in fact it works with all known implementations, and C++11 and later do require contiguous storage, so it's guaranteed to work with them.

As to why I don't like the latter as well: first, because it's longer and harder to read. Second, because it requires that you initialize the contents of the string with data you don't care about, then immediately write over that data (yes, the time to initialize is usually trivial compared to the reading, so it probably doesn't matter, but to me it still feels kind of wrong). Third, in a text file, position X in the file doesn't necessarily mean you'll have read X characters to reach that point -- it's not required to take into account things like line-end translations. On real systems that do such translations (e.g., Windows) the translated form is shorter than what's in the file (i.e., "\r\n" in the file becomes "\n" in the translated string) so all you've done is reserved a little extra space you never use. Again, doesn't really cause a major problem but feels a little wrong anyway.


I think best way is to use string stream. simple and quick !!!

#include <fstream>
#include <iostream>
#include <sstream> //std::stringstream
int main() {
    std::ifstream inFile;
    inFile.open("inFileName"); //open the input file

    std::stringstream strStream;
    strStream << inFile.rdbuf(); //read the file
    std::string str = strStream.str(); //str holds the content of the file

    std::cout << str << "\n"; //you can do anything with the string!!!
}

You may not find this in any book or site but I found out that it works pretty well:

ifstream ifs ("filename.txt");
string s;
getline (ifs, s, (char) ifs.eof());

Try one of these two methods:

string get_file_string(){
    std::ifstream ifs("path_to_file");
    return string((std::istreambuf_iterator<char>(ifs)),
                  (std::istreambuf_iterator<char>()));
}

string get_file_string2(){
    ifstream inFile;
    inFile.open("path_to_file");//open the input file

    stringstream strStream;
    strStream << inFile.rdbuf();//read the file
    return strStream.str();//str holds the content of the file
}

I figured out another way that works with most istreams, including std::cin!

std::string readFile()
{
    stringstream str;
    ifstream stream("Hello_World.txt");
    if(stream.is_open())
    {
        while(stream.peek() != EOF)
        {
            str << (char) stream.get();
        }
        stream.close();
        return str.str();
    }
}

If you happen to use glibmm you can try Glib::file_get_contents.

#include <iostream>
#include <glibmm.h>

int main() {
    auto filename = "my-file.txt";
    try {
        std::string contents = Glib::file_get_contents(filename);
        std::cout << "File data:\n" << contents << std::endl;
    catch (const Glib::FileError& e) {
        std::cout << "Oops, an error occurred:\n" << e.what() << std::endl;
    }

    return 0;
}

I could do it like this:

void readfile(const std::string &filepath,std::string &buffer){
    std::ifstream fin(filepath.c_str());
    getline(fin, buffer, char(-1));
    fin.close();
}

If this is something to be frowned upon, please let me know why


I don't think you can do this without an explicit or implicit loop, without reading into a char array (or some other container) first and ten constructing the string. If you don't need the other capabilities of a string, it could be done with vector<char> the same way you are currently using a char *.

참고URL : https://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring

반응형