Fstream некорректно работает. Хелп!?

Тема в разделе "Общие вопросы по С и С++", создана пользователем shadowofjustice, 24 дек 2010.

Статус темы:
Закрыта.
  1. shadowofjustice

    shadowofjustice Гость

    Здравствуйте. В общем проблема такая.
    Иммется один проект, в котором обрабатывается некоторым образом матрица и выводится потоком в файл через fstream
    (пробовал и бинарный ostream). Затем чуть позже эта матрица читается из того же самого файла и записывается в другую переменную. Все работает безупречно.

    Затем создается новый проект, в рабочую директорию складывается тот самый файл с матрицей и также производится попытка чтения в переменную. Результат - никакой.

    Стоит отметить, что все переменные объявлены одинаково. И, кстати, что примечательно. Если в первом проекте не создавать файл в начале, а сразу попробовать прочитать - то тоже все схватывает хорошо. :/ Суть проблемы понять не могу. Файл один и тот же, реализация одна. Результаты разные.

    Приведу примеры кода:

    Все в одном проекте
    Код (C++):
    int mem;
    mem=8*5;
    double *matr;
    matr=(double *)malloc(mem*sizeof(double));

    /*тут идет заполнение матрицы*/

    fstream output;
    output.open("inA.txt",ios_base::out|ios_base::trunc);
    output.write((char *)&matr,sizeof(matr));
    output.close();

    double *A;
    A=(double *)malloc(mem*sizeof(double));

    ifstream input;
    input.open("inA.txt",ios_base::in);
    input.read((char *) &A,sizeof(A));
    input.close();
    В другом проекте:
    Код (C++):
    mem=8*5;
    double *A;
    A=(double *)malloc(mem*sizeof(double));

    ifstream input;
    input.open("inA.txt",ios_base::in);
    input.read((char *) &A,sizeof(A));
    input.close();
     
  2. ierofant

    ierofant Гость

    В певом проекте работа идёт с тектовым файлом, во втором с бинарным. Так и задумано?


    Добавлено: Флаг ios_base::binary во втором проекте попробуйте поменять на ios_base::in
     
  3. shadowofjustice

    shadowofjustice Гость

    да, сорри за неточность.
    там на самом деле было ios_base::in

    я пробовал и бинарный формат тоже в обоих случаях. Ни при out;trunc и in, ни в бинарном виде - не работает :(
     
  4. ierofant

    ierofant Гость

    Код (C++):
    input.read((char *) &A,sizeof(A));
    A ведь и так указатель. Зачем вы передаёте указатель на указатель?
     
  5. shadowofjustice

    shadowofjustice Гость

    нет. на деле тоже не помогает.
     
  6. ierofant

    ierofant Гость

    Посмотрите ещё раз предыдущее сообщение. Из-за того что мы с вами пмшем в одно время, всё запутолось.
     
  7. shadowofjustice

    shadowofjustice Гость

    и еще. что примечательно:
    когда только выделиляется память под A - ее первое значение по адресу *А = -6.2774385622041925e+066 (и соответсвенно *(А+1)=-6.2774385622041925e+066, *(А+2)=-6.2774385622041925e+066 и т.д. ),
    затем после чтения из файла значения меняются на -2.6569842580370804e+303. В файле, естественно, хранятся не такие числа.
    Это скорее всего из-за того, что адрес памяти меняется почему-то после чтения. Хотя он меняется после чтения в обоих проектах, но во втором выводит как раз некорректные значения.

    Добавлено:
    нет, по прежнему не помогает :(
     
  8. ierofant

    ierofant Гость

    Код (C++):
    ((char *)&matr,sizeof(matr))
    ((char *) &A,sizeof(A))
    Везде поменяйте на:
    Код (C++):
    ((char *) matr,sizeof(mem*sizeof(double)))
    ((char *) A,sizeof(mem*sizeof(double)))

    Добавлено: Потому что вы сохранеяте не переменную, а её адрес.
     
  9. shadowofjustice

    shadowofjustice Гость


    хмм. нет, не помогает. Таким образом он вобще ничего не выводит в файл.
    и Вы допустили ошибку, сказав чуть выше, что я передаю указатель на указатель вот тут:
    Код (C++):
    input.read((char *) &A,sizeof(A));
    & Это ж вроде ссылка на переменную. а (char *) - это приведение к типу. Т.е. получается я указываю на адрес памяти, где начало матрицы А и считываю оттуда sizeof(A) байт.
    или я что-то путаю. в общем - то вопрос не в этом. В первом проекте все работает корректно с таким кодом. Он, кстати, взят из книжек. Почему я не могу размножить этот файл и читать его разными проектами. вот в чем дело :(
     
  10. ierofant

    ierofant Гость

    Нет я всё верно сказал!
    double *matr; это указатель

    a & - это оператор взятия адреса. &matr - это указатель на указатель.

    Код (C++):
    output.write((char *)&matr,sizeof(matr));
    Здесь вы записываете адрес указателя в файл. В одной программе у вас всё работает, потому что адреса все те же самые. Вы же видите, что в файле у вас совершенно не те данные.
     
  11. ierofant

    ierofant Гость

    Вот этот код работает:
    Код (C++):
    #include <iostream>
    #include <fstream>

    int main ()
    {
    int size = 8*5;
    double *mass = new double [size];
    for (int i = 0; i < size; i++) mass [i] = i;

    std::ofstream out ("file", std::ios::out | std::ios::trunc);
    out.write ((char*) mass, size * sizeof (double));
    out.close ();

    double *a = new double [size];
    std::ifstream in ("file");
    in.read ((char*) a, size * sizeof (double));
    in.close ();

    for (int i = 0; i < size; i++) std::cout << a [i] << std::endl;
    delete[] mass, a;
    return 0;
    }
     
  12. ierofant

    ierofant Гость

    Только мне не понятно, зачем вам нужны массивы именно в динамической памяти... Не легче ли обычный массив создать.
     
  13. shadowofjustice

    shadowofjustice Гость

    О, спасибо! точно! теперь дошло до меня вроде бы!! вот почему файл получается всего 4 байта всегда. :(
    насчет динамического массива - моя программа будет работать с большимим объемами данных (матрицы порядка 1000000 на 1000000) и заранее размер будет неизвестен. Эти матрицы хранятся в бинарном файле. Мне необходимо их будет загрузить в оперативную память и обработать.
    кстати Ваш пример будет работать с динамическими массивами? я похоже слабо понимаю в указателях\ссылках, поэтому как мне адаптировать Ваш код под динамические массивы любой величины?
    Огромное спасибо!!
     
  14. ierofant

    ierofant Гость

    Код (C++):
    double *mass = new double [size];
    Вот динамический массив создаётся размером size.
     
  15. shadowofjustice

    shadowofjustice Гость

    а если я все же malloc буду применять? суть не изменится?
    или возникнут подводные камни?
     
  16. ierofant

    ierofant Гость

    malloc это функция языка C, оставленная в С++ для совместимости.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей