Форум программистов, компьютерный форум CyberForum.ru

Чтение массива из файла - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.88
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 01:22     Чтение массива из файла #1
Здравствуйте, господа.

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

Если у вас есть время прочитать о том, что у меня не получается сделать, буду очень признателен.

Мне необходимо сделать две функции - записи данных в файл и чтения их из него.

Для записи у меня 5 целочисленных переменных (назовём их, например, value_1 - value_5), а также трёхмерный массив int huge a1 [100][80][24].

Функция записи в файл у меня выглядит след. образом:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void save_game ()
{
    fstream fp;
    fp.open ("save.sav", ios::out);
    fp << n << " " << load_map << " " << local_pos << " " << map_locations << " " << start_map << " ";
    for (n = 0; n < 100; n++)
    for (i = 0; i < 80; i++)
    for (j = 0; j < 24; j++)
    fp << location[n][i][j] << " ";
    cout << "Saving complete" << endl << endl << "Press any key to quit";
    getch ();
    exit (EXIT_SUCCESS);
}
Функция чтения из файла у меня выглядит след. образом:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int load_game ()
{
    fstream fp;
    fp.open ("save.sav", ios::in);
    fp >> n >> load_map >> local_pos >> map_locations >> start_map;
    cout << n << load_map << local_pos << map_locations << start_map;
    local_map_value = n;
    for (n = 0; n < 100; n++)
    for (i = 0; i < 80; i++)
    for (j = 0; j < 24; j++)
    fp >> location[n][i][j];
    n = local_map_value;
    cout << "Loading complete" << endl << endl << "Press any key to quit";
    getch ();
    exit (EXIT_SUCCESS);
    return n, location[n][i][j], load_map, local_pos, map_locations, start_map;
}
На самом деле, из функции чтения выход всё же не осуществляется, идёт переход на другую функцию, которая уже будет использовать переменные из файла.

Создание файла и сохранение абсолютно всех переменных осуществляется прекрасно. Если сменить расширение файла, который мы создаём, на .txt, то можно даже узнать, что сохраняются именно те значения, которые надо. Проблема в том, что читаются лишь некоторые переменные - точнее, только первые из них. Сначала я думал, что дело в том, что я не так использовал fstream. Когда я попробовал использовать fprintf и fscanf, то проблема всё равно осталась. Потом я решил, что дело в цикле for - попробовал использовать некоторые другие способы. Разумеется, это тоже не помогло.

Для проверки, что же в итоге происходит со значениями, которые не читает из файла, я написал вот такое и увидел, что все значения он показывает как нули:

C++
1
2
3
4
5
6
7
8
9
10
    for (n = 0; n < 100; n++)
    {
    for (i = 0; i < 80; i++)
    {
    for (j = 0; j < 24; j++)
    {
    cout << location[n][i][j];
    }
    }
    }
В чём тут может быть дело?

Заранее благодарю за возможные ответы.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.12.2010, 01:22     Чтение массива из файла
Посмотрите здесь:

Чтение двухмерного массива из файла C++
чтение массива структуры из файла C++
C++ Чтение массива из файла
C++ Чтение из файла массива
Чтение массива из файла C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 05:15     Чтение массива из файла #2
Цитата Сообщение от YourLastSong Посмотреть сообщение
exit (EXIT_SUCCESS);
Вообще по этому оператору программа завершает свою работу.

Цитата Сообщение от YourLastSong Посмотреть сообщение
exit (EXIT_SUCCESS);
return n, location[n][i][j], load_map, local_pos, map_locations, start_map;
Учитывая вышенаписанное до реторна дело никогда не дойдет, к тому же реторн может возвращать только одно значение.

Цитата Сообщение от YourLastSong Посмотреть сообщение
for (n = 0; n < 100; n++)
for (i = 0; i < 80; i++)
for (j = 0; j < 24; j++)
fp >> location[n][i][j];
Оно то конечно хорошо, но полагаться на то, что файл всегда будет содержать правильные данные в нужном количестве не стоит. Лучше проверять флаги состояние потока после чтения. Для этого есть 3 функции:
fstream::eof(); - возвращает 1, если достигли конца файла;
fstream::fail(); - возвращает 1, если по каким-либо причинам не смогли прочитать данные, но в потоке остались данные доступные для чтения;
fstream::bad(); - возвращает 1, если по каким-либо причинам данные не были считаны и дальнейшее чтение не возможно.
Если один из этих флагов будет установлен, дальнейшая работа с потоком будет не вожможна до сброса всех флагов функцией fstream::clear();
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 12:37  [ТС]     Чтение массива из файла #3
Вообще по этому оператору программа завершает свою работу.
Да, я знаю:

На самом деле, из функции чтения выход всё же не осуществляется, идёт переход на другую функцию, которая уже будет использовать переменные из файла.
Учитывая вышенаписанное до реторна дело никогда не дойдет, к тому же реторн может возвращать только одно значение.
Он там и не нужен вообще, но да, спасибо.

Оно то конечно хорошо, но полагаться на то, что файл всегда будет содержать правильные данные в нужном количестве не стоит. Лучше проверять флаги состояние потока после чтения.
Как эти флаги можно использовать конкретно у меня? Пример сможете дать?

Просто с этими флагами ни разу не работал.

И будет ли всё это работать в борланде?

Добавлено через 1 час 22 минуты
Выдаётся ошибка:

Temporary used for parameter 1 in call to 'istream::operator >> (int &)'
Происходит это в данном месте:

Код
fp >> location [n][i][j]
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 14:34     Чтение массива из файла #4
Цитата Сообщение от YourLastSong Посмотреть сообщение
C++
1
2
fstream fp;
 fp.open ("save.sav", ios::in);
Сразу не обратил внимание, тип fstream используется для открытия файлов для чтения\записи, по умолчанию файл открывается в режиме ios::in|ios::out, и если файл с таким именем уже существует, то он удаляется. Если требуется прочитать существующий файл, то нужно использовать режим ios::in|ios::out|ios::app (чтение произвольно, запись в конец файла) или ios::in|ios::out|ios::ate (и чтение и запись произвольно по файлу). Или же, раз чтение и запись разнесены по отдельным функциям, использовать типы ifstream и ofstream соответственно.
Цитата Сообщение от YourLastSong Посмотреть сообщение
Как эти флаги можно использовать конкретно у меня? Пример сможете дать?
Что-то вроде этого
C++
1
2
3
4
5
6
fp >> location[n][i][j];
if (fp.fail())
{
   cout << "Can not read from file." << endl;
   exit(1);
}
Цитата Сообщение от YourLastSong Посмотреть сообщение
Выдаётся ошибка:

Temporary used for parameter 1 in call to 'istream::operator >> (int &)'
Происходит это в данном месте:

C++
1
fp >> location [n][i][j]
Это не ошибка, а предупреждение. Что-то не так с location [n][i][j]. Раньше ее не было?
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 14:45  [ТС]     Чтение массива из файла #5
Раньше ее не было?
Нет, не было.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 14:50     Чтение массива из файла #6
Значит были какие-то исправления в коде?
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 14:56  [ТС]     Чтение массива из файла #7
Значит были какие-то исправления в коде?
Нет, она была с самого начала, как только стал использовать fstream.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 15:09     Чтение массива из файла #8
In C++, a variable or parameter of reference type must be assigned a reference to an object of the same type. If the types do not match, the actual value is assigned to a temporary of the correct type, and the address of the temporary is assigned to the reference variable or parameter.

The warning means that the reference variable or parameter does not refer to what you expect, but to a temporary variable, otherwise unused.
Если я правильно понял, то location [n][i][j] не соответствует типу int.
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 15:11  [ТС]     Чтение массива из файла #9
Если я правильно понял, то location [n][i][j] не соответствует типу int.
У меня int huge location [n][i][j].
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 15:17     Чтение массива из файла #10
Цитата Сообщение от YourLastSong Посмотреть сообщение
int huge
Что это за тип такой?
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 15:31  [ТС]     Чтение массива из файла #11
Что это за тип такой?
Когда пытался сделать массив location [n][i][j] появилось сообщение, что данный массив имеет слишком большой размер, открыл help и увидел, что надо использовать int huge.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 15:37     Чтение массива из файла #12
Судя по всему оператор взять из потока >> с таким типом работать не умеет. Можно попробовать завести int'овую переменную, читать из файла в нее, а потом приравнивать ее элементу массива.
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 15:48  [ТС]     Чтение массива из файла #13
Судя по всему оператор взять из потока >> с таким типом работать не умеет. Можно попробовать завести int'овую переменную, читать из файла в нее, а потом приравнивать ее элементу массива.
У меня в борланде не получается создать трёхмерный массив такого размера без использования int huge вообще.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 15:58     Чтение массива из файла #14
Я понял, я имею ввиду такую конструкцию
C++
1
2
fp >> buf; // buf типа int
location [n][i][j] = buf; // на крайний случай location [n][i][j] = (int huge)buf;
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 16:20  [ТС]     Чтение массива из файла #15
В общем, я решил записывать данные в файл location [100][80][24], а вот для считывания из файла сделал массив типа int location1 [50][40][12].

Код
int location1[50][40][12];
int huge location[100][80][24];

void load_game ()
{
	ifstream fp;
	fp.open ("save.txt", ios::in);
	fp >> n >> load_map >> local_pos >> map_locations >> start_map;
	cout << n << load_map << local_pos << map_locations << start_map;
	getch ();
	local_map_value = n;
	for (n = 0; n < 50; n++)
	for (i = 0; i < 40; i++)
	for (j = 0; j < 12; j++)
	fp >> location1[n][i][j];
	for (n = 0; n < 50; n++)
	for (i = 0; i < 40; i++)
	for (j = 0; j < 12; j++)
	location[n][i][j] = location1[n][i][j];
	for (n = 50; n < 100; n++)
	for (i = 40; i < 80; i++)
	for (j = 12; j < 24; j++)
	fp >> location1[n-50][i-40][j-12];
	for (n = 50; n < 100; n++)
	for (i = 40; i < 80; i++)
	for (j = 12; j < 24; j++)
	location[n][i][j] = location1[n-50][i-40][j-12];
	for (n = 0; n < 100; n++)
	{
	for (i = 0; i < 80; i++)
	{
	for (j = 0; j < 24; j++)
	{
	cout << location[n][i][j];
	}
	}
	}
	n = local_map_value;
	cout << "Loading complete" << endl << endl << "Press any key to quit";
	getch ();
}

void save_game ()
{
	ofstream fp;
	fp.open ("save.txt", ios::out);
	fp << n << " " << load_map << " " << local_pos << " " << map_locations << " " << start_map << " ";
	for (n = 0; n < 100; n++)
	for (i = 0; i < 80; i++)
	for (j = 0; j < 24; j++)
	fp << location[n][i][j] << " ";
	location1[n-50][i-40][j-12] = location[n][i][j];
	cout << "Saving complete" << endl << endl << "Press any key to quit";
	getch ();
	exit (EXIT_SUCCESS);
}
Теперь не все элементы массива нули, однако всё же проблема осталась.

Что тут можно исправить, чтобы всё выводилось?
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
12.12.2010, 16:36     Чтение массива из файла #16
Ээ... всетаки использовать в качестве буфера целый массив довольно накладно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
for (n = 0; n < 100; n++)
   for (i = 0; i < 80; i++)
      for (j = 0; j < 24; j++)
      {  
         fp >> buf;
         // отладочная часть
         if (fp.eof() || fp.fail() || fp.bad())
            cout << "fail = " << fp.fail() << "; eof = " << fp.eof() << "; bad = " << fp.bad() 
                   << "; n = " << n << "; i = " << i << "; j = " << j << endl;
         // конец отладочной части
         location[n][i][j] = buf;
      }
YourLastSong
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 112
12.12.2010, 17:04  [ТС]     Чтение массива из файла #17
Спасибо.

Кстати, давно уже хотел узнать - есть ли какие-либо функции для изменения заголовка окна консоли и для того, чтобы убрать мигающий курсор в консоли?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.12.2010, 12:11     Чтение массива из файла
Еще ссылки по теме:

Чтение и вывод массива из файла C++
Чтение массива из файла C++
Чтение массива из файла C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
13.12.2010, 12:11     Чтение массива из файла #18
Цитата Сообщение от YourLastSong Посмотреть сообщение
чтобы убрать мигающий курсор в консоли?
В conio.h есть функция
C
1
2
3
4
5
6
7
8
9
10
11
void _setcursortype(int cur_t);
 
/*Description
 
Selects cursor appearance.
 
Sets the cursor type to
 
_NOCURSOR   Turns off the cursor
_NORMALCURSOR   Normal underscore cursor
_SOLIDCURSOR    Solid block cursor*/
Цитата Сообщение от YourLastSong Посмотреть сообщение
есть ли какие-либо функции для изменения заголовка окна консоли и для того, чтобы убрать мигающий курсор в консоли?
Можно использовать API функции.
C++
1
2
3
4
5
6
SetConsoleTitleA(IN LPCSTR lpConsoleTitle);
 
SetConsoleCursorInfo(
    IN HANDLE hConsoleOutput,
    IN CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
    );
Если я правильно понял названия этих функций, находятся в windows.h за описанием в msdn.
Yandex
Объявления
13.12.2010, 12:11     Чтение массива из файла
Ответ Создать тему
Опции темы

Текущее время: 11:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru