Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[c++] чтение файла

14K
17 декабря 2007 года
v0lkan0
32 / / 02.03.2007
при помощи какой функции можно все содержимое текстового файла содрать в char* s; если можно то пожалуйста на примере.
314
17 декабря 2007 года
fanto
374 / / 15.02.2003
Начнем с того, что s суть указатель и ничего более....
А так:
int fd=open(<имя>, <флаги>);
if(fd == -1) perror("Can't open file");
read(fd, buf, count);
где buf -- указатель, на ранее выделенную (malloc) память
count -- сколько читать

в man`е все подробно описано....
14K
17 декабря 2007 года
v0lkan0
32 / / 02.03.2007
я использую функцию read(char* buf, streamsize num);

 
Код:
char* sq;
ifstream f("handlog.txt");
  if(!f){
    cout<<"netu file";
    return 1;
  }
sq=new char[[COLOR="Red"]sizeof f[/COLOR]];
f.read(sq,[COLOR="#ff0000"]sizeof f[/COLOR]);


что мне написать вместо красного (так как если я пишу так как написано красным, то в sq не записывается весь файл, а только небольшая часть его), что бы в sq записалась вся инфа из файла (файл текстовый).
350
18 декабря 2007 года
cheburator
589 / / 01.06.2006
fanto, речь о C++, а не о C.
v0lkan0, насчет sizeof - см. твою соседнюю тему про строки.
Я бы сделал примерно так:
 
Код:
ifstream file ("somefile.txt", ios_base::in | ios_base::bin);
if (!file)
  // Файл открыть не удалось. Какой-то код обработки ошибки, например, такой:
  throw exception ("Can't open somefile.txt");
file.seekg (0, ios_base::end); // Позиционируемся в конец (только для того, чтобы узнать размер файла)
streamoff filesize = file.tellg();
char *buf = new char [filesize+1];
file.seekg (0); // Обратно в начало
file.read (buf, filesize);

P. S. Код не тестировался
P. P. S.
 
Код:
if(!f){
    cout<<"netu file";
    return 1;
  }

- ошибки не принято выводить в cout, принято в cerr
14K
19 декабря 2007 года
v0lkan0
32 / / 02.03.2007
Код:
ifstream f("test");
    ofstream fu("out");

    if(!f){
        throw exception ("Can't open somefile.txt");
    }
    f.seekg(0,ios_base::end);
    streamoff filesize = f.tellg();
    [COLOR="Red"]char* sq=new char[filesize+1];[/COLOR]
    f.seekg(0);
    f.read(sq,filesize);
    cout<<sq<<"q"<<endl;


количество символов в файле прощитывает нормально, но когда создает sq (красным), то длинна строки почему-то становится равна не filesize+1, а больше, в следствие чего это происходит???

далее я эту строку передаю в метод класса filter:
Код:
char* filter(char* s)
    {
        char* str;
        int j=0;
        for(int i=0;i<=[COLOR="Red"]s[/COLOR];i++)
        {
          if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
          {
            j++;
          }
        }
        str=new char[j+1];
        cout<<j<<" j"<<endl;
        j=0;
        for(i=0;i<=[COLOR="Red"]s[/COLOR];i++)
        {
          if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
          {
            str[j]=s;
            j++;
          }
        }
        return str;
    }

здесь в первом цикле происходит подсчет кол. русских букв, и после его создается строка равная этому кол. потом во втором цикле происходит запись букв в эту строку. Но так как строка S поступает сюда длиннее чем она должна быть изходя из кол символов в файле, то тут происходят непонятные мне вещи и J становится равным не кол. русских букв в файле, а больше! Вследствие чего строка str (хранящая эти рус буквы) становится длинне самого J.
Даже когда ограничиваю циклы (красным) жестко на кол. символов (например в файле 4 символа из них один рус) то строка str все равно становится равна не 1, а 6, получается пишется какой-то мусор...

Объясните пожалуйста почему так происходит!?
16K
19 декабря 2007 года
HolyDel
11 / / 03.03.2006
не
for(int i=0;i<=s;i++)
а
for(int i=0;i<=strlen(s);i++)
350
19 декабря 2007 года
cheburator
589 / / 01.06.2006
Цитата: HolyDel

for(int i=0;i<=strlen(s);i++)


Правильно.
Но если не хочешь, чтобы длина строки подсчитывалась при каждой итерации, вычисли ее заранее:

 
Код:
const int slen = strlen(s);
for(int i=0;i<=slen;++i)

P. S.
Не пойму, почему всех студентов учат писать i++...
По-моему, давно все должны понимать, что лучше ++i
---
v0lkan0, учись пользоваться отладчиком, будешь проблемы находить быстрее.
Видимо, ошибка в моем коде, после чтения из файла надо дописать закрывающий нуль:
 
Код:
...
f.read(sq,filesize);
[color=red]sq[filesize] = 0;[/color]
320
19 декабря 2007 года
m_Valery
1.0K / / 08.01.2007
Цитата: cheburator

...
P. S.
Не пойму, почему всех студентов учат писать i++...
По-моему, давно все должны понимать, что лучше ++i
...


Вообще-то,Сам(Стауструп) пишет и так и так...Нигде вроде на это внимания не акцентирует,а вот Джосьюттис пишет следующее...

Цитата: Nicolai M. Josuttis

 
Код:
...
for(pos = coll.begin();pos != coll.end();++pos){        ...
}...

Обратите внимание на использование префиксной версии оператора ++.
Возможно, в этом случае она работает эффективнее постфиксной версии,которая создает временный обьект для возвращения старой позиции итератора.Из-за этого в общем случае рекомендуется использовать ++pos вместо pos++,а следуещее решение нежелательно.
 
Код:
...
for(pos = coll.begin();pos != coll.end();pos++){
         ...
}...

350
19 декабря 2007 года
cheburator
589 / / 01.06.2006
[quote=Цитата из Herb Sutter, GotW #55]
 
Код:
// Каноническая форма постинкремента:
    T T::operator++(int)
    {
      T old( *this ); // Запоминаем предыдущее значение
      ++*this;        // Всегда реализуем постинкремент через преинкремент
      return old;     // Возвращаем предыдущее значение
    }

Рекомендация: Всегда старайтесь придерживаться естественной семантики для перегруженных операторов. "Делай так, как сделал бы int", т. е. следуйте семантике встроенных типов.
[/quote]

Отсюда видно, что типичный постинкремент всегда "хуже" прединкремента (в том числе, даже для встроенных типов, и уж естественно - для итераторов STL), потому что создается временный объект, поэтому надо пользоваться вторым, когда есть возможность (если, конечно, пользователь уверен, что этот тип придерживается семантики встроенных типов).
14K
19 декабря 2007 года
v0lkan0
32 / / 02.03.2007
Цитата:
v0lkan0, учись пользоваться отладчиком, будешь проблемы находить быстрее.
Видимо, ошибка в моем коде, после чтения из файла надо дописать закрывающий нуль:
Код:
...
f.read(sq,filesize);
sq[filesize] = 0;



да, ошибка была сдесь и по этому примеру я еще подправил у себя такую же ошибку. Спс.

Но есть еще одна проблема. Теперь длинна sq равна кол. символов в файле, НО при каждом переводе строки в файле она прибавляет +2 к своей длинне. В итоге при фильтрации я снова вылажу за "границы строки" и попадаю в мусор.

Я заменила for на while и делаю в нем проверку на перевеод строки в результате чего уменьшаю len:

 
Код:
while(i<len)
        {
          if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
            {
            j++;
            }
          if(s=='\n')
            len--;
          i++;
        }

Все работает нормально.
Может есть способ проще красивее?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог