Его использование довольно простое.
builder . -64bit -Debug
Значит, исходный код находится в текущем каталоге, а конфигурация компиляции - 64-битная версия отладки.
Вам нужно всего лишь изменить глобальные переменные конфигурации в скрипте, которые указывают визуальную студию и cmake.
SET VISUAL_STUDIO_9_HOME =
SET CMAKE_HOME =
@echo off
rem ===== Usage
rem builder c:\workspace\project1 -32bit -Release
rem builder . -64bit -Debug
rem Global configuration variables. Should be update based on your system
SET VISUAL_STUDIO_9_HOME=c:\Program Files\Microsoft Visual Studio 9.0
SET CMAKE_HOME=c:\Documents and Settings\stumk\My Documents\toolkit\cmake
rem First parameter is project folder path
SET PROJECT_DIR=%1
rem Add executables into path
rem Only add them once
if NOT DEFINED SETENV SET SETENV=0
if %SETENV% EQU 0 SET PATH=%CMAKE_HOME%\bin;%VISUAL_STUDIO_9_HOME%\Common7\Tools;%PATH%
SET SETENV=1
rem Go to project director
cd %PROJECT_DIR%
rem Create build folder, don't mess the source code with visual studio project files
md build
rem Go to build folder
cd build\
rem Set visual studio environment variables
call vsvars32.bat
rem Second parameter defines 32 bit or 64 bit compilation
if "%2"=="-32bit" (
cmake.exe .. -G "Visual Studio 9 2008"
)
if "%2"=="-64bit" (
cmake.exe .. -G "Visual Studio 9 2008 Win64"
)
rem Third parameter defines debug or release compilation
if "%3"=="-Debug" (
cmake.exe --build . --target ALL_BUILD --config Debug
)
if "%3"=="-Release" (
cmake.exe --build . --target ALL_BUILD --config Release
)
rem Go to source code directory and finalize script
cd ..
@echo on
Используйте
#include <iostream>
#include <sstream>
#include <fstream>
int main()
{
std::ifstream input("file.txt");
std::stringstream sstr;
while(input >> sstr.rdbuf());
std::cout << sstr.str() << std::endl;
}
или что-то очень близко. У меня нет stdlib ссылки открытой для перепроверения меня.
Да, я понимаю, что не записал эти slurp
функция, как спросили.
Что-то вроде этого не должно быть слишком плохим:
void slurp(std::string& data, const std::string& filename, bool is_binary)
{
std::ios_base::openmode openmode = ios::ate | ios::in;
if (is_binary)
openmode |= ios::binary;
ifstream file(filename.c_str(), openmode);
data.clear();
data.reserve(file.tellg());
file.seekg(0, ios::beg);
data.append(istreambuf_iterator<char>(file.rdbuf()),
istreambuf_iterator<char>());
}
преимущество здесь состоит в том, что мы делаем резерв сначала, таким образом, мы не должны будем выращивать строку, поскольку мы читаем вещи в. Недостаток - то, что мы делаем это символ символом. Более умная версия могла захватить целое чтение buf и затем назвать потерю значимости.
И самое быстрое (что я знаю о, обесценивая файлы с отображенной памятью):
std::string str(static_cast<std::stringstream const&>(std::stringstream() << in.rdbuf()).str());
Это требует дополнительного заголовка <sstream>
для строкового потока. (Эти static_cast
необходимо с тех пор operator <<
возвраты простое ostream&
, но мы знаем, что в действительности it’s stringstream&
, таким образом, бросок безопасен.)
Разделение в несколько строк, перемещая временный файл в переменную, мы получаем более читаемый код:
std::string slurp(std::ifstream& in) {
std::stringstream sstr;
sstr << in.rdbuf();
return sstr.str();
}
Или, еще раз в одной строке:
std::string slurp(std::ifstream& in) {
return static_cast<std::stringstream const&>(std::stringstream() << in.rdbuf()).str();
}
Самый короткий вариант: , Живой На Coliru
std::string str(std::istreambuf_iterator<char>{ifs}, {});
, Это требует заголовка <iterator>
.
были некоторые отчеты, что этот метод медленнее, чем предварительное выделение строки и использование std::istream::read
. Однако на современном компиляторе с оптимизациями, включенными, это больше, кажется, не имеет место, хотя относительная производительность различных методов, кажется, высоко зависимый компилятора.
Никогда не пишите в станд.:: символ константы строки * буфер. Никогда! Выполнение так является серьезной ошибкой.
Резерв () располагают с интервалами для целой строки в Вашем станд.:: строка, считайте блоки из своего файла разумного размера в буфер и добавьте () его. То, насколько большой блоки должны быть, зависит от Вашего входного размера файла. Я вполне уверен, все другие портативные и совместимые STL механизмы сделают то же (все же может выглядеть более симпатичным).
Можно использовать 'станд.:: getline' функция, и определяют 'eof' как разделитель. Получающийся код немного неясен хотя:
std::string data;
std::ifstream in( "test.txt" );
std::getline( in, data, std::string::traits_type::to_char_type(
std::string::traits_type::eof() ) );
См. этот ответ по подобному вопросу.
Для Вашего удобства, я повторно отправляю решение CTT:
string readFile2(const string &fileName)
{
ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);
ifstream::pos_type fileSize = ifs.tellg();
ifs.seekg(0, ios::beg);
vector<char> bytes(fileSize);
ifs.read(bytes.data(), fileSize);
return string(bytes.data(), fileSize);
}
Это решение закончилось приблизительно в на 20% более быстрое время выполнения, чем другие ответы, представленные здесь при взятии среднего числа 100 выполнений против текста Моби Дика (1.3M). Не плохо для портативного решения C++, я хотел бы видеть результаты mmap'ing файл ;)
Вот версия, пользующаяся новой библиотекой файловой системы с довольно устойчивой проверкой ошибок:
#include <cstdint>
#include <exception>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <string>
namespace fs = std::filesystem;
std::string loadFile(const char *const name);
std::string loadFile(const std::string &name);
std::string loadFile(const char *const name) {
fs::path filepath(fs::absolute(fs::path(name)));
std::uintmax_t fsize;
if (fs::exists(filepath)) {
fsize = fs::file_size(filepath);
} else {
throw(std::invalid_argument("File not found: " + filepath.string()));
}
std::ifstream infile;
infile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
infile.open(filepath.c_str(), std::ios::in | std::ifstream::binary);
} catch (...) {
std::throw_with_nested(std::runtime_error("Can't open input file " + filepath.string()));
}
std::string fileStr;
try {
fileStr.resize(fsize);
} catch (...) {
std::stringstream err;
err << "Can't resize to " << fsize << " bytes";
std::throw_with_nested(std::runtime_error(err.str()));
}
infile.read(fileStr.data(), fsize);
infile.close();
return fileStr;
}
std::string loadFile(const std::string &name) { return loadFile(name.c_str()); };