весь файл из ifstream >> string
От: Ignoramus  
Дата: 23.05.05 11:49
Оценка:
Вопрос вроде простой, но туплю

Как прочитать весь файл из ifstream в один большой string?

Самый простой стандартный способ?

(Если просто ifs >> s то читается строка до первого разделителя между словами...)

Заранее спасибо.
Re: весь файл из ifstream >> string
От: avitya  
Дата: 23.05.05 11:56
Оценка: 4 (1)
Здравствуйте, Ignoramus, Вы писали:

I>Вопрос вроде простой, но туплю


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)


I>Заранее спасибо.

string s;
copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));
Re: весь файл из ifstream >> string
От: A. Fedotov Украина  
Дата: 23.05.05 12:01
Оценка: 4 (1)
Здравствуйте, Ignoramus, Вы писали:


    fstream file("c:\\1.txt");
    string str;

    copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));
Re: весь файл из ifstream >> string
От: zelyony  
Дата: 23.05.05 12:02
Оценка:
file.seekg( 0, ios_base::end);
pos_type len = file.tellg();
file.seekg( 0);
str.resize( len);
file.read( (char*)str.data(), len); // нехорошо
Posted via RSDN NNTP Server 1.9
Re: весь файл из ifstream >> string
От: Chorkov Россия  
Дата: 23.05.05 12:09
Оценка:
Здравствуйте, Ignoramus, Вы писали:

    string s;
    ifstream inp("test.txt");
    getline(inp, s, '\0');
Re: весь файл из ifstream >> string
От: ssm Россия  
Дата: 23.05.05 12:18
Оценка:
Здравствуйте, Ignoramus, Вы писали:


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


так делают парни из boost:

void load_file(std::string& s, std::istream& is)
{
   s.erase();
   if(is.bad()) return;
   //
   // attempt to grow string buffer to match file size,
   // this doesn't always work...
   s.reserve(is.rdbuf()->in_avail());
   char c;
   while(is.get(c))
   {
      // use logarithmic growth stategy, in case
      // in_avail (above) returned zero:
      if(s.capacity() == s.size())
         s.reserve(s.capacity() * 3);
      s.append(1, c);
   }
}
Re: весь файл из ifstream >> string
От: Valodzka Беларусь  
Дата: 23.05.05 21:37
Оценка: 5 (1) +1
Здравствуйте, Ignoramus, Вы писали:

I>Как прочитать весь файл из ifstream в один большой string?


Обединяя всё вышенаписанное в нормальный вариант:

typedef std::istream_iterator<char> IIC;

file.seekg( 0, std::ios_base::end);
std::fstream::pos_type size = file.tellg();
file.seekg( 0);
//теперь так
std::string str_file;
str_file.reserve(size);
std::copy(IIC(file), IIC(), std::back_inserter(str_file));
Не перебивайте меня, когда я вас перебиваю
Re[2]: весь файл из ifstream >> string
От: Erop Россия  
Дата: 24.05.05 04:39
Оценка:
Здравствуйте, Valodzka, Вы писали:

V>
V>typedef std::istream_iterator<char> IIC;

V>file.seekg( 0, std::ios_base::end);
V>std::fstream::pos_type size = file.tellg();
V>file.seekg( 0);
V>//теперь так
V>std::string str_file;
V>str_file.reserve(size);
V>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>


А что случится, если в файле встретится байт '\0'?
Я так понимаю, что такой байт в строчку добавлять нельзя?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: весь файл из ifstream >> string
От: alexeiz  
Дата: 24.05.05 05:47
Оценка: 3 (1)
"Ignoramus" <18039@users.rsdn.ru> wrote in message
news:1186457@news.rsdn.ru
> Вопрос вроде простой, но туплю
>
> Как прочитать весь файл из ifstream в один большой string?
>
> Самый простой стандартный способ?

Например, такой (очень простой, не правда ли?):
#include <iostream>              
#include <fstream>               
#include <sstream>               
                                 
using namespace std;             
                                 
int main(int argc, char * argv[])
{                                
    ifstream in(argv[1]);        
    ostringstream out;           
    out << in.rdbuf();  // <---------
    cout << out.str();           
}
Posted via RSDN NNTP Server 1.9
Re: весь файл из ifstream >> string
От: Аноним  
Дата: 24.05.05 07:04
Оценка: 1 (1) +1
Здравствуйте, Ignoramus, Вы писали:

I>Вопрос вроде простой, но туплю


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)


I>Заранее спасибо.


ifstream file("some.txt");
typedef istreambuf_iterator<char> iter;
string str( (iter(file)), iter() );
Re[3]: весь файл из ifstream >> string
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 07:35
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Valodzka, Вы писали:


V>>
V>>typedef std::istream_iterator<char> IIC;

V>>file.seekg( 0, std::ios_base::end);
V>>std::fstream::pos_type size = file.tellg();
V>>file.seekg( 0);
V>>//теперь так
V>>std::string str_file;
V>>str_file.reserve(size);
V>>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>>


E>А что случится, если в файле встретится байт '\0'?

E>Я так понимаю, что такой байт в строчку добавлять нельзя?

А почему в std::string нельзя '\0' добавить? В чем проблема-то?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 09:30
Оценка: 6 (3)
Здравствуйте, Ignoramus, Вы писали:

Сравнил скорость всех предложенных методов, в конце постинга сабж.
Сразу оговорюсь, что на корректность теста я не претендую, просто было интерестно померять время в конкретном случае, а именно взял текстовый файл на 6,5 метров. MSVC 7.1 /O2
Вот тестец(оставил все, как было в оригинальных постах):


#include <fstream>
#include <algorithm>
#include <string>
#include <sstream>


using namespace std;

void readFile1(const char *fileName)
{
    std::ifstream ifs(fileName, std::ios::binary);
    std::string s;
    copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));

    std::cout << " " << s.length() << " ";
}

void readFile2(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    std::string str;

    std::copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));

    std::cout << " " << str.length() << " ";
}

void readFile3(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    string str;

    file.seekg( 0, ios_base::end);
    std::ifstream::pos_type len = file.tellg();
    file.seekg( 0);
    str.resize( len);
    file.read( (char*)str.data(), len); 

    std::cout << " " << str.length() << " ";
}

void readFile4(const char *fileName)
{
    string s;
    ifstream inp(fileName, std::ios::binary);
    getline(inp, s, '\0');

    std::cout << " " << s.length() << " ";
}

void readFile5(const char *fileName)
{
    string s;
    ifstream is(fileName, std::ios::binary);

    //
    // attempt to grow string buffer to match file size,
    // this doesn't always work...
    s.reserve(is.rdbuf()->in_avail());
    char c;
    while(is.get(c))
    {
        // use logarithmic growth stategy, in case
        // in_avail (above) returned zero:
        if(s.capacity() == s.size())
            s.reserve(s.capacity() * 3);
        s.append(1, c);
    }

    std::cout << " " << s.length() << " ";
}

void readFile6(const char *fileName)
{
    typedef std::istream_iterator<char> IIC;

    std::ifstream file(fileName, std::ios::binary);    

    file.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = file.tellg();
    file.seekg( 0);
    
    std::string str_file;
    str_file.reserve(size);
    std::copy(IIC(file), IIC(), std::back_inserter(str_file));

    std::cout << " " << str_file.length() << " ";

}

void readFile7(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);
    ostringstream out;           
    out << in.rdbuf(); 

    string s;
    out.str().swap(s); 

    std::cout << " " << s.length() << " ";
}

typedef void (*PF)(const char*);

class FReadFile
{
public:
    FReadFile(const char *fileName)
        :    fileName(fileName)
    {
    }

    void operator()(PF pf) const
    {
        pf(fileName);
    }

private:
    const char *fileName;
};

int main() 
{ 
    

    const size_t readersCount = 7;
    PF readers[readersCount] = {
        readFile1, readFile2, readFile3, 
        readFile4, readFile5, readFile6, 
        readFile7
    };
    
    FReadFile func("c:\\temp\\prof\\test.txt");

    for(int i = 0; i < 10; ++i)
    {
        std::for_each(readers, readers + readersCount, func);
        std::cout << i << "\n";
    }    

}


собственно сабж.

"Method Name","% in Method","% with Children","Called","Average"
"readFile5",   "43,9",       "44,0",           "10",    "3836250,8"
"readFile2",   "17,5",       "17,6",           "10",    "1526903,1"
"readFile6",   "14,9",       "15,0",           "10",    "1304416,2"
"readFile1",   "11,6",       "11,8",           "10",    "1015325,8"
"readFile4",    "7,1",        "7,3",           "10",     "622452,2"
"readFile7",    "3,6",        "3,8",           "10",     "317294,6"
"readFile3",    "0,3",        "0,4",           "10",      "27201,5"


выводы делать не возьмусь, замечу только, что бустовская попытка оптимизации окончилась фиаско
для меня фаворит readFile7, хотя конечно readFile3 делает всех, но ИМХО на больших размерах файлов может быть эффективней читать порциями, а не все одной сарделькой.
Re[2]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 09:40
Оценка: +1
Здравствуйте, ssm, Вы писали:

Так ведь:

ssm>
ssm>void readFile3(const char *fileName)
ssm>{
ssm>    std::ifstream file(fileName, std::ios::binary);
ssm>    string str;

ssm>    file.seekg( 0, ios_base::end);
ssm>    std::ifstream::pos_type len = file.tellg();
ssm>    file.seekg( 0);
ssm>    str.resize( len);
ssm>    file.read( (char*)str.data(), len); 

ssm>    std::cout << " " << str.length() << " ";
ssm>}
ssm>


некорректен.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 09:49
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, ssm, Вы писали:


E>Так ведь:


ssm>>
ssm>>void readFile3(const char *fileName)
ssm>>


E>некорректен.



"оставил все, как было в оригинальных постах"

Re[4]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 09:53
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, eao197, Вы писали:


E>>Здравствуйте, ssm, Вы писали:


E>>Так ведь:


ssm>>>
ssm>>>void readFile3(const char *fileName)
ssm>>>


E>>некорректен.



ssm>

ssm>"оставил все, как было в оригинальных постах"


А если бы завалилось все?

Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: отчет DevPartner
От: zelyony  
Дата: 24.05.05 09:57
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, ssm, Вы писали:


E>Так ведь:


ssm>>
ssm>>void readFile3(const char *fileName)
ssm>>{
ssm>>    std::ifstream file(fileName, std::ios::binary);
ssm>>    string str;

ssm>>    file.seekg( 0, ios_base::end);
ssm>>    std::ifstream::pos_type len = file.tellg();
ssm>>    file.seekg( 0);
ssm>>    str.resize( len);
ssm>>    file.read( (char*)str.data(), len);   //(*)

ssm>>    std::cout << " " << str.length() << " ";
ssm>>}
ssm>>


E>некорректен.



а так?
    file.read( &str[0], len);   //(*)
Re[4]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 10:04
Оценка:
Здравствуйте, zelyony, Вы писали:

Z>Здравствуйте, eao197, Вы писали:


E>>Здравствуйте, ssm, Вы писали:


E>>Так ведь:


ssm>>>
ssm>>>void readFile3(const char *fileName)
ssm>>>{
ssm>>>    std::ifstream file(fileName, std::ios::binary);
ssm>>>    string str;

ssm>>>    file.seekg( 0, ios_base::end);
ssm>>>    std::ifstream::pos_type len = file.tellg();
ssm>>>    file.seekg( 0);
ssm>>>    str.resize( len);
ssm>>>    file.read( (char*)str.data(), len);   //(*)

ssm>>>    std::cout << " " << str.length() << " ";
ssm>>>}
ssm>>>


E>>некорректен.



Z>а так?

Z>
Z>    file.read( &str[0], len);   //(*)
Z>


Имхо, это тоже самое.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 10:15
Оценка: :)
Здравствуйте, eao197, Вы писали:

E>А если бы завалилось все?


но мы ведь не из робкого десятка

E>Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?


никак размер файла все-таки 6,5 метров
Re[2]: еще один отчет
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 10:41
Оценка:
Тоже решил пойти по следам ssm.

Собрал вот такую программку:
#include <iostream>
#include <iterator>
#include <fstream>
#include <algorithm>
#include <functional>
#include <string>
#include <sstream>
#include <ctime>
#include <map>

using namespace std;

void readFile1(const char *fileName)
{
    std::ifstream ifs(fileName, std::ios::binary);
    std::string s;
    copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));

    std::cout << " " << s.length() << " ";
}

void readFile2(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    std::string str;

    std::copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));

    std::cout << " " << str.length() << " ";
}

void readFile4(const char *fileName)
{
    string s;
    ifstream inp(fileName, std::ios::binary);
    getline(inp, s, '\0');

    std::cout << " " << s.length() << " ";
}

void readFile5(const char *fileName)
{
    string s;
    ifstream is(fileName, std::ios::binary);

    //
    // attempt to grow string buffer to match file size,
    // this doesn't always work...
    s.reserve(is.rdbuf()->in_avail());
    char c;
    while(is.get(c))
    {
        // use logarithmic growth stategy, in case
        // in_avail (above) returned zero:
        if(s.capacity() == s.size())
            s.reserve(s.capacity() * 3);
        s.append(1, c);
    }

    std::cout << " " << s.length() << " ";
}

void readFile6(const char *fileName)
{
    typedef std::istream_iterator<char> IIC;

    std::ifstream file(fileName, std::ios::binary);    

    file.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = file.tellg();
    file.seekg( 0);
    
    std::string str_file;
    str_file.reserve(size);
    std::copy(IIC(file), IIC(), std::back_inserter(str_file));

    std::cout << " " << str_file.length() << " ";

}

void readFile7(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);
    ostringstream out;           
    out << in.rdbuf(); 

    string s;
    out.str().swap(s); 

    std::cout << " " << s.length() << " ";
}

typedef void (*PF)(const char*);
typedef std::map< std::string, PF > func_map_t;

struct    meter_t
    :    public std::unary_function< func_map_t::value_type, void >
    {
        int    m_argc;
        char **    m_argv;

        meter_t( int argc, char ** argv )
            :    m_argc( argc )
            ,    m_argv( argv )
            {}

        result_type
        operator()( argument_type a )
            {
                std::cout << a.first << " " << std::flush;

                std::clock_t start = std::clock();

                for( int i = 1; i < m_argc; ++i )
                    (*a.second)( m_argv[ i ] );

                std::clock_t finish = std::clock();

                std::cout << "duration: " << double( finish - start ) / CLOCKS_PER_SEC
                        << std::endl;
            }
    };

int main( int argc, char ** argv ) 
{ 
    func_map_t readers;
    readers[ "readFile1" ] = &readFile1;
    readers[ "readFile2" ] = &readFile2;
    readers[ "readFile4" ] = &readFile4;
    readers[ "readFile5" ] = &readFile5;
    readers[ "readFile6" ] = &readFile6;
    readers[ "readFile7" ] = &readFile7;
    
  std::for_each(
        readers.begin(), readers.end(),
        meter_t( argc, argv ) );
}


Тестировал на файлах от ~35Mb до ~50Mb. Забавно, что readFile2, readFile4, readFile6 выдают в результате неправильные размеры

На Visual С++ 7.1 получил:
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 22.92
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 36.843
readFile4  6  5  3  3  5 duration: 0.047
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 25.655
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 35.42
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.984


На Borland C++ 5.6:
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 17.203
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 50.234
readFile4  6  5  3  3  5 duration: 0.016
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 34.938
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 62.593
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 23.282


На MinGW C++ (3.2.3 20030504-1):
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 34.9
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 62.562
readFile4  6  5  3  3  5 duration: 0.157
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 55.983
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 59.307
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.47


Еще под Linux-ом осталось подсчитать.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: весь файл из ifstream >> string
От: Valodzka Беларусь  
Дата: 24.05.05 10:53
Оценка:
Здравствуйте, Erop, Вы писали:

E>А что случится, если в файле встретится байт '\0'?

E>Я так понимаю, что такой байт в строчку добавлять нельзя?

Точно где это написано не помню, но по стандарту std::string должен корректно обрабатывать любые символы, в том числе '\0'
Не перебивайте меня, когда я вас перебиваю
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.