programing

ASCII 파일 전체를 C++ std:: 문자열로 읽습니다.

codeshow 2023. 4. 17. 22:08
반응형

ASCII 파일 전체를 C++ std:: 문자열로 읽습니다.

파일 전체를 메모리로 읽어 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()

좋은 생각 있어요?

몇 가지 가능성이 있습니다.마음에 드는 것은 스트링 스트림을 중개자로 사용하는 것입니다.

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

이제 "file.txt"의 내용은 다음 문자열로 제공됩니다.buffer.str().

또 다른 가능성(저도 물론 좋아하지 않지만)은 당신의 원래와 훨씬 더 비슷합니다.

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); 

공식적으로는 C++98 또는 03 규격에서는 동작할 필요가 없습니다(데이터를 연속적으로 저장하기 위해 문자열이 필요하지 않습니다). 그러나 실제로는 알려진 모든 구현에서 동작하며, C++11 이후에는 연속 스토리지가 필요하므로 이들 표준과 함께 동작할 수 있습니다.

내가 후자를 싫어하는 이유는 첫째, 읽기가 더 길고 어렵기 때문이다.둘째, 불필요한 데이터로 문자열의 내용을 초기화하고 즉시 데이터를 덮어쓰도록 요구하기 때문입니다(그렇습니다.초기화 시간은 보통 읽기보다 짧기 때문에 상관없을 수도 있지만, 나에게는 여전히 잘못된 느낌입니다).셋째, 텍스트 파일에서 파일 내의 위치 X가 해당 지점에 도달하기 위해 반드시 X자를 읽어야 하는 것은 아닙니다.행 끝 변환 등을 고려할 필요는 없습니다.이러한 변환을 실행하는 실제 시스템(Windows 등)에서는 변환된 폼이 파일 내에 있는 폼보다 짧기 때문에(즉, 파일 내의 "\r\n"이 변환된 문자열의 "\n"이 됩니다).사용하지 않는 약간의 여분의 공간을 예약하는 것 뿐입니다.다시 말씀드리지만, 큰 문제는 없지만 어쨌든 조금 잘못된 것 같습니다.

업데이트: 이 방법은 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 c c c 한 것 같습니다. C의 것과 혼동하신 것 같습니다.fopen.

Edit: 문자열 생성자에 대한 첫 번째 인수 주위에 괄호를 추가합니다.이것들은 필수입니다.이것은, 「가장 귀찮은 해석」이라고 불리는 문제를 회피합니다.이 경우, 실제로는 통상처럼 컴파일 에러는 발생하지 않지만, 흥미로운(읽기:잘못 읽음) 결과를 얻을 수 있습니다.

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>());

스트링 스트림을 사용하는 것이 가장 좋은 방법이라고 생각합니다.심플하고 빠르게!!!

#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!!!
}

어떤 책이나 사이트에서도 찾을 수 없는 내용이지만, 저는 이것이 꽤 잘 작동한다는 것을 알게 되었습니다.

#include <fstream>
// ...
std::string file_content;
std::getline(std::ifstream("filename.txt"), file_content, '\0');

다음 두 가지 방법 중 하나를 사용해 보십시오.

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
}

대부분의 스트림에서 작동하는 다른 방법을 알아냈어요 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();
    }
}

glibmm 를 사용하는 경우는, 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;
}

이렇게 할 수 있어요.

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

만약 이것이 눈살을 찌푸릴 일이라면 이유를 알려주세요.

명시적 또는 암묵적 루프 없이는 이 작업을 수행할 수 없습니다. char 배열(또는 다른 컨테이너)을 먼저 읽고 문자열을 구성하는 10을 읽지 않고서는 말이죠. 이 할 수 .vector<char> 하고 있는 으로.char *.

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

반응형