| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Центр помощи > [C] текстовый файл |
| Автор: Zaulyx 30.11.2008, 15:55 |
| здравствуйте все! Помогите пожалуйста. Нужно написать программу на Си: имеется текстовый файл в котором есть матрица(не обязательно квадратная) с числами с плавующей точкой. Пользователь вводит номера столбцов и операции с ними, и результирующий столбец сохраняется в другом текстовом файле. Возможно что пользователь просто напишет номера столбцов без операций. Помогите пожалуйста! |
| Автор: Zaulyx 6.12.2008, 18:05 |
| такой вопрос: а как каждое число из матрицы занести в массив? помогите написать эту часть проги плз |
| Автор: taiven 6.12.2008, 20:18 |
| матрица какого вида и откуда ты её берёшь, из файла? |
| Автор: Zaulyx 6.12.2008, 21:16 |
| матрица любая по размеру с числами с плавающей точкой. беру из файла текстового |
| Автор: taiven 7.12.2008, 12:39 | ||
попробуй так:
в итоге получишь матрицу размера MxN. но это если файл имеет правильный формат т.е. никаких лишних пробелов в конце строк не должно быть и т.д. |
| Автор: Zaulyx 7.12.2008, 14:24 |
| а как реализовать операции со столбцами? как я понимаю когда вводится номер столбца мы его записываем в переменную i, когда записываем номер второго, третьего и тд.. то мы должны все время менять переменную i на другую..но так можно делать бесконечно.. и как быть со знаками операции? |
| Автор: Dmi3ev 7.12.2008, 14:42 |
| лучше создать структуру или класс, которая (который) будет хранить индекс столбеца1, индекс столбца2, знак операции |
| Автор: Zaulyx 7.12.2008, 14:51 |
| Да через структуру намного проще будет, но думаю есть какой-нибудь простой алгоритм, чтобы реализовать это без структуры, хотя не знаю.. |
| Автор: taiven 7.12.2008, 15:21 | ||||||
честно говоря не совсем понимаю, что ты имеешь ввиду... вот тебе вывод первого столбца:
поменяй j на единицу и будет считывать второй столбец и т.д. или я что-то непонимаю?
в смысле? |
| Автор: Zaulyx 7.12.2008, 15:54 |
| нет, смотри. вводится какая-либо операция допустим 2+4 или 3/5 где цифры это номера столбцов т.е. в первом случае 2й столбец складывается с 4м, а во втором числа 3его столбца делятся на числа 5го. т.е. for (i=1; i=M; i++) matrix[2][j]+matrix[4][j] и полученный результат выводится |
| Автор: taiven 7.12.2008, 20:34 | ||
вот приблизительно так можно сделать для сложения(вывод на экран):
переделай это под свои нужды и всё. |
| Автор: taiven 7.12.2008, 21:03 |
| кстати, а операция должна всегда проводиться с двумя столбцами или нет, т.е. всегда должен быть вид типа 2+4 или возможно и 2+4+3? |
| Автор: Zaulyx 8.12.2008, 13:19 |
| нет сколько угодно столбцов могут участвовать в операции... Кстати я подумал как можно организовать не только сложение но и другие арифм операции. Я думаю через switch и case...это самый рациональный способ или можно более умно поступить? |
| Автор: Dmi3ev 8.12.2008, 17:45 | ||||||
1
это уже попахивает созданием анализатора выражений, хоть и не самого сложно, но все же... 2 Тогда и массив может быть неизвестного размера. Значит нужно использовать указатели. 3 Читать из файла массив советую, используя ifstream, это гораздо удобнее, чем предлагает taiven:
Вообщем достаточно это все трудоемко... Хотя реализуемо Добавлено через 2 минуты и 8 секунд 4
можно и указатели на функции использовать. Смотреть надо. |
| Автор: Zaulyx 9.12.2008, 15:52 | ||
вот смысл моей идеи. поправьте плз код
|
| Автор: taiven 9.12.2008, 18:49 |
| А ты кроме сложения другие операции сделал уже? Оно у тебя работает? Тебе осталось только выбор операции сделать? |
| Автор: Zaulyx 9.12.2008, 18:58 |
| ну как правильность я пока не могу проверить - компилятор не пашет... можно сказать на бумажке это написал... не знаю как насчет правильности но хотел чтобы это выглядело так: пользователь вводит номер столбца вводит операцию дальше идет выбор из операций записывает этот столбец в result[a] потом вводится другой столбец. в зависимости от операции к result[a] прибавляется/вычитается и тд.. этот столбец. и так пока пользователь не введет '=' это как я себе представляю должно работать....но на деле может и не получится, по-этому прошу поправить если я в силу своей неопытности в програмировании отклонился от своей идеи |
| Автор: taiven 9.12.2008, 19:28 | ||||||||||
на бумажке это конечно круто ну и по коду: в строке
в строке
switch`у нельзя скормить строку, тут лучше сделать так
|
| Автор: Zaulyx 9.12.2008, 20:00 | ||
| вот насчет возможности деления на ноль не знаю как учесть... вот переработанный код
PS и дев-Си не хочет работать) пишет проект не откомпилирован....хотя компилица успешно...не хочет запускаться и все тут |
| Автор: taiven 9.12.2008, 21:15 | ||
если скомпилилось успешно, то в папке проекта должен появится экзешник, запусти его из командной строки и всё. |
| Автор: Zaulyx 9.12.2008, 21:22 |
| о спасибо, а по коду есть какие-нибудь советы? кстати твоя часть кода-считывание из файла не загружается. т.е. нажимаю на екзешный файл и вылетает... |
| Автор: taiven 9.12.2008, 21:51 |
| В смысле вылетает? С ошибкой? что пишет? |
| Автор: Zaulyx 9.12.2008, 21:58 |
| вылетает на подобии того как в паскале когда не пишешь readln; в конце и при запуске вылетает... вот и здесь что-то типо того...без ошибок.. |
| Автор: taiven 9.12.2008, 22:08 | ||||
| запусти файл из командной строки(перетащи файл консольное окно и нажми <ENTER>) или же вот эту часть кода
измени на
и откомпиль снова скорее всего ты путь к файлу на свой не изменил. |
| Автор: Zaulyx 9.12.2008, 22:16 |
| хм...ну я создал по адресу файл file.txt.. c:\file.txt вот содержимое файла: 1.0 3.0 3.2 32.1 4.1 5.11 32.3 1.1 а когда запускаю пишет Error т.е. файл не проходит проверку на null... |
| Автор: taiven 9.12.2008, 22:26 | ||||
попробуй положить file.txt в папку с экзешником и поменяй это
на это
|
| Автор: Zaulyx 9.12.2008, 22:30 |
| та же фигня... |
| Автор: taiven 9.12.2008, 22:48 | ||
| мда... тут либо ты создал не потому адресу, либо еще могу предположить, что у тебя расширения файлов на компе не отображаются и ты создав текстовый файл прибавил к нему .txt. попробуй снова положить файл на диск С(файл не переименовывай) и исправь код на
|
| Автор: Zaulyx 9.12.2008, 22:57 | ||
хм.. жалуется на то что char o не объявлена.... и жалуется на запись файла(не могу разобраться как записать массив в файл...) |
| Автор: taiven 10.12.2008, 16:39 | ||
Вот, пробуй, я особо не тестил)
|
| Автор: Zaulyx 10.12.2008, 17:28 | ||||
| Спасибо огромное, не представляешь как помог, особенно в конце семестра вот у меня вопросы по коду: 1. За что отвечает переменные Index и value Index это что-то вроде i? т.е. он пробегает по строке? 2. вот функиця memset(s,c,n) как в учебнике написано размещает литеру c в первых n позициях стринга s и возвращает s. А вот в коде я не очень понял трактовку.. 3. я правильно понял работу цикла?
пока не дошли до конца файла { в ch записывается текущий символ в файле если ch десятичная цифра или встречается "-" { то.... двигаемся к следущей цифре в строке(т.е. к след столбцу?) считываем эту цифру } в переменную value записываем str в double типе(т.е он сразу записывает первую строку матрицы?) в matrix[i][j] считываем по строчно. (т.е идет как раз заполнения массива числами из файла?) M=i; N=j-1; это все понятно Если, проходя по строке нашли конец строки то i== j=0 (но когда же мы доходим до конца строки мы должны наоборот занулить i и j++ или нет?) Ну и собственно 2 вопрос по поводу мемсет. 4.
что значит for(;;) ?? |
| Автор: taiven 10.12.2008, 18:26 | ||||||||||
1. index это индекс
это же можно переписать так:
value временная переменная можно обойтись и без неё, т.е вместо этого
это
2. memset обнуляет массив str(стирает предыдущую запись). т.е. заполняем его символом '\0'. 3. Всё верно вроде
i это строки, j стобцы (matrix[№строки][№столбца]) |
| Автор: taiven 10.12.2008, 20:49 | ||
бесконечный цикл, за остановку которого отвечает это условие
|
| Автор: Zaulyx 12.12.2008, 17:56 |
| препод попросил реализовать скобки, чтобы можно было использовать (1+2)/(3+4) такого вида.... вот я думаю какой цикл нужен?И вообще реально впихнуть это в нашу программу? и нужно сделать динамический массив для матрицы |
| Автор: taiven 12.12.2008, 20:47 | ||||||
это уже анализатор выражений получается, т.е. тут надо будет разбирать строку такого вида (1+2)/(3+4), иначе я думаю не получится...
думаю нет.
ну и в чём проблема? |
| Автор: Zaulyx 12.12.2008, 20:59 |
| нет сделать динамический массив это не проблема, а вот переделывать 2ю часть проги это проблема. я как думаю нужно сделать цикл когда встречается "(" и когда встречается ")" , то то что в скобках записывать в какой то двумерный массив, M[наш столбец получившийся][1].... только вот можно ли такое реализовать? технически это возможно как нибудь? добавить в case эти скобки...и.... |
| Автор: taiven 13.12.2008, 00:26 | ||
дело не столько в возможности или невозможности это реализовать технически, сколько в том, что хочет от тебя препод: видеть такую запись (1+2)/(3+4)(строку) для ввода или ему в принципе подходит, то что есть просто нужно доработать. |
| Автор: Zaulyx 13.12.2008, 20:23 |
| он просто хочет видеть доработанную программу....вот моя идея как сделать это: значит как: считаем 1+2 записываем результат в result[i] и result[i] дозаписываем в наш исходный файл как последний столбец (5 столбец) дальше считаем 3+4 тоже записываем как последний (6 столбец) потом делим 5 на 6 в итоге реализуем скобки... дальше записываем в исходный файл исходную матрицу и записываем result[i] который 5 /6 в оутпут файл... думаю нужно сделать считывание матрицы как функцию, чтобы после изменения сразу на экране всплывал 5й столбец, в кэйс или даже в while добавить симол ")", т.е. после нажатия его спрашиваем продолжить вычисления? записываем result[i] обнуляем его и продолжаем со второй скобкой... |
| Автор: taiven 13.12.2008, 21:44 |
| Ну, ты же приблизительно знаешь, как хочешь сделать. Пробуй, а там посмотрим. |
| Автор: Zaulyx 13.12.2008, 22:29 | ||
а как вот этот кусок оформить как функцию?
|
| Автор: taiven 13.12.2008, 22:59 | ||||||
приблизительно так:
ну и вызов
вот это
из функции main надо убрать |
| Автор: Zaulyx 14.12.2008, 14:16 | ||
как-то так....но не знаю как доработать. Добавил в кейс ')' и после ее нажатия result[i] должен обнулятся и добавлятся новый столбец в исходный файл, а как на самом деле получается или нет не могу сказать...
|
| Автор: taiven 14.12.2008, 15:33 |
| Этот код одна сплошная ошибка... Кто же функцию внутри функции main объявляет? Ты это компилировал вообще? Ладно, вот есть выражение (1+2)/(1+3), как ты собираешься это вводить? Алгоритм, пошаговый, можешь написать? |
| Автор: Zaulyx 14.12.2008, 15:45 |
| сначала вводим 1+2 как изначально было до введения скобок дальше нажимаем ")" результат записываем в resul[i] (как и было раньше) добавляем result[i] в исходную матрицу как последний столбец. выводим получившуюся матрицу на экран зануляем result[i] теперь вводим 1+3 нажимаем ")" результат в result[i] добавляем в исходную матрицу как последний столбец (Если в исходной матрице было 3 столбца теперь там их 5) вводим 4/5 нажимаем "=" записываем в result[i] записываем в output файл записанные выше столбцы 4 и 5 в исходную матрицу стираем |
| Автор: taiven 14.12.2008, 18:43 |
| не знаю, все равно не могу сообразить как сделать. пробуй сделать сам, если есть конкретные вопросы ,спрашивай. |
| Автор: Zaulyx 14.12.2008, 19:38 |
| при вызове функции чтения из файла мы должны вбивать кол-во столбцов и строк? |
| Автор: Zaulyx 14.12.2008, 19:59 |
| а мы можем как нибудь открыть файл чтобы его можно было и читать и в него дописывать информацию? |
| Автор: taiven 14.12.2008, 20:04 |
| в смысле в функцию matrix_read_out(fp, &M, &N, matrix);? нет, после выполнения функции M и N, будут содержать размер матрицы |
| Автор: Zaulyx 14.12.2008, 20:21 | ||
вот при компиляции: вбиваем столбец 1 вбиваем операцию - вбиваем столбец 3 вбиваем операцию ) просит вбить столбец выходит но он ведь должен записать в result[i] разность столбцов а потом занулить его и записать нулевой массив в аутпут.тхт ?? или он должен быть в цикле for(;;) ?? |
| Автор: taiven 14.12.2008, 20:32 |
| добавь case ')':break; в switch, чтобы не происходил выход. |
| Автор: Zaulyx 14.12.2008, 20:42 | ||
если я добавлю в кейс то вот это
перестает работать...хотя оно и так не работало...ну а тут оно вообще не играет никакой роли |
| Автор: taiven 14.12.2008, 21:30 |
| ну почему не играет никакой роли, запись в файл-то происходит а вообще мне кажется здесь нужно в свитче сделать еще один свитч(повесить его на case '(' основного свитча), сециально для работы с выражениями в скобках, сделать в нём свой цикл for(;;), и выходить из цикла по нажатию ')'. И массив дополнительный, который будет хранить результат... но я сегодня вряд ли буду уже, что-то писать. |
| Автор: Zaulyx 17.12.2008, 17:17 | ||
вот внес в свитч цикл только как то криво работает, как сделать так чтобы до введения первого столбца можно было делать выбор на скобки?
|
| Автор: taiven 17.12.2008, 17:42 |
| можно использовать строки, тогда можно будет вводить такие конструкции, как "+(", ")=" и т.д. |
| Автор: Zaulyx 17.12.2008, 17:49 |
| т.е. char operation[2] ??? |
| Автор: taiven 17.12.2008, 18:05 |
| char operation[3] Добавлено через 1 минуту и 19 секунд и проверки делать так : if(!strcmp(operation, "+")) ... |
| Автор: taiven 17.12.2008, 19:28 | ||
короче, вот:
вообщем опять же, я особо не тестил поэтому смотри сам. если не поймешь как пользоваться, спрашивай Добавлено через 3 минуты и 59 секунд не, не работает оно всетаки до конца нормально, но такие выражения, как (1+2)/(1+3) вроде считает... |
| Автор: Zaulyx 17.12.2008, 19:59 |
| хм..чтото он опять вылетает при запуске... |
| Автор: taiven 17.12.2008, 20:03 |
| а нет всётаки работает нормально, это я просто подумал, что оно и такие выражения будет нормально считать : 1+(1+1)*(2+2)(по всем правилам математики), но это без ввода строки и её разбора не сделать... т.е. в проге это выражение считается так: сначала это 1+(1+1), а потом умножение на (2+2). Добавлено @ 20:04 пути к файлам проверь. |
| Автор: Zaulyx 17.12.2008, 20:10 |
| а как мне вбивать если хочу (1+2)/(3+4)? в какой последовательности и когда вбивать скобку? |
| Автор: taiven 17.12.2008, 20:21 | ||
так:
проверки на правильность или неправильность ввода нет, поэтому вводить надо внимательно. |
| Автор: Zaulyx 17.12.2008, 20:25 |
| спс большое за помощь пойду разбираться с кодом |
| Автор: taiven 17.12.2008, 20:28 |
| и ещё учти, что со вложенными скобками прога не работает. |
| Автор: Zaulyx 18.12.2008, 19:34 | ||
| у меня встала загвостка насчет динамического массива. прочитал этот топик http://forum.vingrad.ru/topic-189118.html но там все рассмотрено для integer массива, а вот с double проблемы возникли
|
| Автор: taiven 18.12.2008, 19:39 |
| А зачем тебе вообще выделять память динамически? И какой массив ты хочешь сделать динамическим? |
| Автор: Zaulyx 18.12.2008, 19:46 |
| мну нужно выделить память динамически для массива матрицы..зачем нужно не знаю но препод требует, аргументировав тем, что если матрица будет размером 2*60 то выделенной памяти то достаточно, а массив будет переполнен.... |
| Автор: taiven 18.12.2008, 21:21 | ||
вот:
незнаю правда или я правильно выделяю и освобождаю память (сишными методами никогда не пользуюсь, тем более для многомерных массивов). и вообще в таком виде в динамическом выделении памяти толку мало, если уж выделять память динамически, то сначала, нужно подсчитать, сколько реально строк и столбцов в файле... |
| Автор: Zaulyx 18.12.2008, 21:43 |
| спасибо огромное! теперь у меня может даже будет зачет по инфе=) |
| Автор: Zaulyx 19.12.2008, 15:44 |
| а что значит и зачем мы записываем (double**) по синтаксису? |
| Автор: taiven 19.12.2008, 17:01 |
| вот http://group9231.narod.ru/ci.htm почитай комментарии(там на C++, но я думаю ты разберёшься, идея та же в принципе) |
| Автор: Zaulyx 19.12.2008, 18:48 | ||
хм... там я не нашел ответа на вопрос
вот в этой строчке каково назначение (double**)? т.е. это указатель на указатель на double... а зачем мы это пишем? |
| Автор: taiven 19.12.2008, 19:44 |
| а, ты имеешь в виду зачем (double**) именно перед функцией malloc? |
| Автор: Zaulyx 19.12.2008, 19:52 |
| вот именно в этой строчке зачем мы пишем double**? вот как я понял malloc возврщает void а нам нужен double... вот как это сформулировать по нормальному?(если я конечно правильно думаю..) |
| Автор: taiven 19.12.2008, 20:01 | ||
это называется приведение типа. |
| Автор: Zaulyx 19.12.2008, 20:08 |
| ясно спасибо) |