Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Существует много путей, Вы выбираете, который является самым изящным для Вас.
Чтение в char*:
ifstream file ("file.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
file.seekg(0, ios::end);
size = file.tellg();
char *contents = new char [size];
file.seekg (0, ios::beg);
file.read (contents, size);
file.close();
//... do something with it
delete [] contents;
}
В станд.:: строка:
std::ifstream in("file.txt");
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
В vector< char>:
std::ifstream in("file.txt");
std::vector<char> contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
В строку, с помощью stringstream:
std::ifstream in("file.txt");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());
file.txt является просто примером, все хорошо работает для двоичных файлов также, просто удостоверьтесь, что Вы используете iOS:: двоичный файл в ifstream конструкторе.
Существует другой поток на этом предмете.
Мои решения от этого потока (обе остроты):
хорошее (см. второе решение Милана):
string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>());
и быстрое:
string str(static_cast<stringstream const&>(stringstream() << ifs.rdbuf()).str());
Вы, кажется, говорите об элегантности как определенное свойство "небольшого кода". Это, конечно, субъективно в некоторой степени. Некоторые сказали бы, что исключение всей обработки ошибок не очень изящно. Некоторые сказали бы, что ясный и компактный код, который Вы понимаете сразу же, изящен.
Запись Ваша собственная функция/метод остроты, которая читает содержание файла, но делает его строгим и безопасным под поверхностью и Вы покроете оба аспекта элегантности.
Все лучшее
/Robert
Мне нравится символ Милана* путь, но со станд.:: строка.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
string& getfile(const string& filename, string& buffer) {
ifstream in(filename.c_str(), ios_base::binary | ios_base::ate);
in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
buffer.resize(in.tellg());
in.seekg(0, ios_base::beg);
in.read(&buffer[0], buffer.size());
return buffer;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "Usage: this_executable file_to_read\n";
return EXIT_FAILURE;
}
string buffer;
cout << getfile(argv[1], buffer).size() << "\n";
}
(с или без ios_base:: двоичный файл, в зависимости от того, хотите ли Вы переведенные новые строки или нет. Вы могли также изменить getfile, чтобы просто возвратить строку так, чтобы Вы не передавали буферную строку в. Затем тест, чтобы видеть, оптимизирует ли компилятор копию при возврате.)
Однако это могло бы выглядеть немного лучше (и быть намного медленнее):
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
string getfile(const string& filename) {
ifstream in(filename.c_str(), ios_base::binary);
in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
return string(istreambuf_iterator<char>(in), istreambuf_iterator<char>());
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "Usage: this_executable file_to_read\n";
return EXIT_FAILURE;
}
cout << getfile(argv[1]).size() << "\n";
}