c чтение матрицы из файла

Я новичок в этом. Я пытаюсь прочитать файл и поместить его в 2D-массив. Вот мой код после вывода файла он отображает мусор в памяти, и цикл никогда не заканчивается, пока не достигнет 50.

Текстовый файл выглядит так

Содержание

  1. Решение
  2. Другие решения
  3. 1 ответ 1
  4. Комментарии
  5. Всего ответов: 2
  6. Используйте требуемые #include s
  7. Подумайте о пользователе
  8. Улучшенная санитария ввода пользователя
  9. Передавать поток, а не имя файла
  10. Использовать лучшую структуру данных
  11. Использование экстрактора friend вместо отдельной функции
  12. Слово об адресации отдельных квадратов
  13. Комментарии

Решение

Я думаю, что-то вроде этого работает

Все строки текста заканчиваются символом «конец строки» « n» или « r n». Это может сигнализировать о переходе к новому ряду символов в массиве.
Так как массив был инициализирован с 0, мы можем использовать его как флаг конца строки в выводе, но лучше было бы вычислить размер массива при чтении его (если все строки имеют одинаковый размер).

Другие решения

Попробуйте это, но убедитесь, что входная матрица в map.txt точно 50 * 50 символов, в противном случае вы можете получить неопределенные результаты.
( include «stdafx.h» отсутствует, потому что я использую g ++ вместо MS Visual Studio, но вы можете добавить это включение для предварительно скомпилированных заголовков, если вы создали свой проект так, как это нужно VS)

Если вы пытаетесь сделать то, что я думаю, попробуйте это:

код на си вроде,сколько смотрела по форумам, код правильный грешу на ввод размерности с клавиатуры выводит матрицу заполненную нулями когда добавила

стало выводить «Open file error»

подскажите,пожалуйста, в чем проблема

1 ответ 1

Проблема у вас в том, что не открывается файл matrixA.txt . Скорее всего, его просто нет в текущем каталоге, из которого запускается ваша программа.

То, что раньше этого сообщения не было, не говорит о том, что все было хорошо — просто программа не жаловалась, что ей на самом деле плохо. 🙂

Я пытаюсь познакомиться с C ++ 11/14, поэтому, пожалуйста, скажите, можно ли написать приведенный ниже код более «современным» способом. Или, конечно, если это можно улучшить каким-либо образом.

Функция buildInput считывает содержимое файла и создает с ним матрицу.

Функция создает вход для Sokoban из файла. По сути, он строит «карту» (матрицу) с размещенными на ней объектами нескольких типов.

Файл имеет следующий формат:

Например, для следующего содержимого файла:

код будет строить матрицу

Комментарии

Всего ответов: 2

Я вижу некоторые вещи, которые могут помочь вам улучшить ваш код.

Используйте требуемые #include s

Код использует CODE_1. Это было несложно сделать вывод, но это помогает рецензентам, если код завершен. Полный набор необходимых включений выглядит следующим образом:

Подумайте о пользователе

В приведенном примере ввода требуется 21 число, чтобы компьютер мог создать матрицу, содержащую только 16. Там много избыточности! Мне кажется, что простое использование выходного примера в качестве входного формата имело бы гораздо больше смысла и потребовало бы меньше места, меньше печатания и меньше интерпретации.

Улучшенная санитария ввода пользователя

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

Передавать поток, а не имя файла

Текущий дизайн довольно негибкий, поскольку он может использовать только фактический файл в качестве входных данных. Я бы рекомендовал сделать его более общим и принять std::istream & в качестве параметра, а не имени файла.

Использовать лучшую структуру данных

Выбор вектора из векторы для матрицы не очень хороши, потому что в отличие от матрицы, нет ничего, что могло бы гарантировать, что все векторы имеют одинаковый размер. Я бы порекомендовал создать свой собственный объект, который скрывает грязные детали реального хранилища (это может быть CODE_4), но может выполнять проверку и извлечение границ с использованием той же системы координат. Пример показан ниже.

Использование экстрактора friend вместо отдельной функции

Вместо того, чтобы иметь отдельную функцию, было бы лучше иметь возможность писать код что-то вроде этого:

Для этого мы могли бы написать экстрактор. Вот эскиз примера:

Слово об адресации отдельных квадратов

Вопрос в комментариях заключался в том, может ли выполнение математики (умножение) быть более продолжительным чем адресация вектора векторов. На моей 64-битной машине Linux, использующей gcc 6.2.1 с оптимизацией -O3, я кодировал две разные версии.

Во-первых, вот тестовый исходный код:

Обратите внимание, что это плохая программа, не требующая полной проверки ошибок, но цель состояла лишь в том, чтобы извлечь язык ассемблера для двух версий CODE_6. Во-первых, эта версия

создал этот код сборки

создал этот код сборки

Я не смог обнаружить каких-либо временных различий с проведенным мною тестированием, но мы видим, что разница в том, что для версии вектора векторов существует 5 выборок памяти против трех для умножающей версии. Если структура находится в кеше (вероятно, в моем тестировании, когда я использовал небольшие измерения), они оба имеют примерно одинаковую продолжительность. В случае отсутствия кэша умножающая версия, скорее всего, будет быстрее.

Я бы всегда рекомендовал вам измерять его на своем компьютере с вашими собственными данными, чтобы определить, что лучше для ваших целей.

Комментарии

В дополнение к отличному ответу @Edwards есть несколько вещей, о которых я хотел бы упомянуть:

Когда вы передать аргумент функции, как здесь:

вы передаете его «по значению», что означает, что выполняется CODE_0), тогда это время копирования станет нетривиальным.

Если вам на самом деле не нужна копия (потому что вы ее где-то храните или хотите изменить, не влияя на вызывающего), тогда вы должны передать все не POD-типы по ссылке на const. Примерно так:

Традиционно считается, что 2D и 3D (или nD для вопрос) объемы должны быть линеаризованы в одномерные массивы путем вычисления одномерного индекса из nD координат. то есть. replace:

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

Существуют также последствия переносимости практически для всех известных мне программ, которые обрабатывают изображения или матрицы, используют это вид линеаризации, и вы должны также, если вы хотите взаимодействовать с ними.

Слишком (не) эффекты этого я написал эталонный тест здесь, на ideone . И я публикую результаты здесь:

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

Источник: computermaker.info

Понравилась статья? Поделиться с друзьями:
Ок! Компьютер
Добавить комментарий