Запись результата вычисления в текстовый файл

Здравствуйте, хотел узнать, как записать результат вычислений в текстовый файл.

Вот мой примитивный калькулятор:

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
    setlocale(LC_ALL,"RUS");
    double a=0,b=0,c=0;
    char d;
    printf ("Введите выражение"); 
    cin>>a>>d>>b;

    switch (d)
    {
    case '+': 
    c=a+b;
    cout <<"Сумма чисел="<< c<<endl;
    break;
    case '-':
    c=a-b;
    cout <<"Разность чисел="<< c<<endl; 
    break;
    case '*': 
    c=a*b; 
    cout <<"Произведение чисел="<< c<<endl;
    break;
    case '/':
    c=a/b; 
    cout <<"Деление чисел="<< c<<endl; 
    break;

    FILE *fp = fopen("123.txt" ,"w"); //тут нерабочая запись всех переменных в текстовый файл
    bool result = fputs(c, fp); 
    fclose(fp);
    return 0;
    }    
    return 0;
}

Подскажите пожалуйста ещё кое что:

  1. как записать переменные и результат вычислений в одномерный массив?
  2. как можно введённое в консоль выражение, например: (54-3*6)/2

Как тут распознать символы и определить их автоматически, что бы потом можно было просто вычислить?

Я думал может быть записать введённую строку в массив, а потом вывести с распознанными символами Double и char. Стоит ли записывать знаки в символьный вид, или они в отдельную категорию входят?

Спасибо за внимание.

Будет лучше если вводить будем строку а не по символу.
a) d[1] = c; //example
b) (54 — 3 * 6) / 2, тут надо проверить все if'ом, прочитать целиком строку, и найти доминирующее выражение(В данном случае скобки, а в скобках умножение, затем только деление)
с) Насколько я знаю, строку в массив не запихнуть, строка это string.

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <string>
using namespace std;
int main()
{
setlocale(LC_ALL,"RUS");
double a=0,b=0,c=0;
char d;
printf ("Введите выражение"); 
cin>>a >>d >>b;
switch (d)
{
case '+': 
c=a+b;
cout <<"Сумма чисел = "<< c<<endl;
break;
case '-':
c=a-b;
cout <<"Разность чисел = "<< c<<endl; 
break;
case '*': 
c=a*b; 
cout <<"Произведение чисел = "<< c<<endl;
break;
case '/':
c=a/b; 
cout <<"Деление чисел = "<< c<<endl; 
break;
ofstream fp("123.txt");
fp<<c;
fp.close();
}
return 0;
}

спасибо Ers, но

a) d[1] = c; //example

  • Кажется не работает. Вставил в новый файл, скомпилировал, запустил, файл с записью не создаётся, создал вручную в той же папке 123.txt, и снова ничего.

b) (54 — 3 * 6) / 2, тут надо проверить все if'ом, прочитать целиком строку, и найти доминирующее выражение(В данном случае скобки, а в скобках умножение, затем только деление)

  • Можно по подробнее, как это прочитать строку. Я помню про Scanf(), но с помощью него можно прочесть только выражения заранее предсказанной длинны и конструкции. Я же хотел бы вне зависимости от количества символов в выражении смочь прочесть её.

с) Насколько я знаю, строку в массив не запихнуть, строка это string.

  • Можно ли тогда разделить строку посимвольно и запихнуть в массив или вектор, если вас не затруднит по подробнее расскажите.
    Извините я ещё зелен в с++, чуток совсем знаю)

поправил, извините за мультипост

Насколько я знаю, строку в массив не запихнуть, строка это string.

Любая строка, на низком уровне языка, есть массив символов. Класс string просто облегчает нам работу со строками. Но не суть.

как можно введённое в консоль выражение, например: (54-3*6)/2

По-простому никак. Нужно писать парсер, который будет анализировать строку и вычленять из нее данные.

Вот пример парсера для систем уравнений, который умеет подобные слагаемые :)

функцию fputs

Скопировал код, при запуске пишет «нет доступа к файлу!» Ни создаёт ни записывает при созданном файле.

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    setlocale(0,""); 
    char * fileName = "C:\\Games\\example.txt";
    FILE * file = fopen(fileName, "w");
    if (file) 
    {
        char * str = "I Like The Coding!"; 
        bool result = fputs(str, file);
        if (!result) 
            cout << "Строка в файл записана успешно!" << endl; 
    }

    else
    cout << "Нет доступа к файлу!" << endl;
    fclose(file);
    return 0;
}

Просто копирую со страницы с уроком.

Eskel, судя по имени файла, ты сидишь под Виндой, и скорее всего это W7 или W8. От Висты и выше операционки очень ревностно относятся к записи файла «не туда». Особенно это касается диска C. Если у тебя система установлена с настройками по умолчанию, попробуй указать имя файла либо вообще без пути, тогда файл должен быть записан в каталог запуска программы (например в тот, где лежит исполняемый файл), либо указать такой путь для файла, который явно разрешён для твоей учётной записи (например c:\users\<username>\Documents...).

Ещё пара уточнений по программе.

(1) Вызов fclose(file) лучше перенести в блок if (file) {...}, поскольку если файл не открыт, то и закрывать его не надо. В данном случае это не особо важно, поскольку fclose() не возбуждает исключение, если закрываемый файл не открыт, но лучше писать аккуратно.

(2) Синтаксис

char * str = "I Like The Coding!";

теперь deprecated, т.е. «не рекомендуемый». Что бы компилятор не давал предупреждений надо писать так:

char str1[] = "I Like The Coding!";  // для строк, которые предполагается модифицировать
char *c = str1;  // работает нормально: символы строки можно читать и записывать
// или так:
const char *str2 = "I Like The Coding!";  // для константных строк
char *c = str2;  // компилятор даёт ошибку "неправильное преобразование указателя"
// однако явное преобразование типа указателя
char *c = (char *)str2;  // компилятор пропускает, 
// но содержимое строки доступно только для чтения
// при попытке записи возбуждается исключение

Спасибо за предложенные варианты.
У меня семёрка, попробовал как вы сказали, но всё равно нет доступа к файлу(

Вот как я ввёл первый вариант:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
setlocale(0,""); 
char * fileName = "C:\Games\example.txt";
FILE * file = fopen(fileName, "w");
if (file) 
{
    char str1[] = "I Like The Coding!";
    char *c = str1;
    bool result = fputs(str1, file);
    if (!result) 
       {
        cout << "Ñòðîêà â ôàéë çàïèñàíà óñïåøíî!" << endl; 
       fclose(file);
       }
}
else
cout << "Íåò äîñòóïà ê ôàéëó!" << endl;
return 0;
}

Попробуй так:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    setlocale(0,""); 
    // бэкслэши в данном случае должны быть сдвоенными!
    // char fileName[] = "C:\\Games\\example.txt";
    char fileName[] = "example.txt";
    FILE * file = fopen(fileName, "w");
    if (file) 
    {
        char str1[] = "I Like The Coding!";
        bool result = fputs(str1, file);
        if (!result) 
        {
            cout << "Строка в файл записана успешно!" << endl; 
        }
        fclose(file);
    }
    else
        cout << "Нет доступа к файлу!" << endl;
    return 0;
}

Благодарю, теперь получается записать, но только если указывать не путь к файлу а только название, то есть:

char fileName[] = "example.txt";

При указании адреса файла, по прежнему не записывает.

Либо (1) пытаешься записать файл в запрещённое, с точки зрения Винды, место, либо (2) не правильно указываешь путь, например с одиночными бэкслэшами, как в твоём посте от 15.12.13.

Есть вопрос немного не по теме, хочу сделать что то типа калькулятора, с помощью борланд билдера, поставил на форму Edit1, Button1 и Label1. Пишу код в кнопку:

#include <vcl.h>
#include <math.h>

#pragma hdrstop

#include "Unit1.h"
    //--------------------------------------------------------           -------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int x, y;
y=Edit1->Text.ToDouble();
x=y;
Label1->Caption=x;        
}
//---------------------------------------------------------------------------

Предполагаю, что записанное в Эдит1 выражение, хотя бы 2+2, должно рассчитываться как если бы я вставил туда переменные для уравнения, то есть за место переменных я пытаюсь ввести всё уравнение, но выдаётся ошибка:
«is not a valid floating point value», то есть «не является допустимым значением с плавающей точкой», хотя я по умолчанию забыл все переменные как «double», но выражение с плавающей точкой это же float? Помогите мне доделать программу и пожалуйста разъясните что именно я сделал не так.

Борланд Билдер, в свою очередь, предполагает, что в Эдит1 пользователем введена строка. И он, на самом деле, прав.

Почему ты считаешь, что выражение, введённое в Эдит1 вообще должно как-то интерпретироваться?

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

float — тип числа с плавающей точкой одинарной точности.
double — тип числа с плавающей точкой двойной точности.

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

PS. С Borland C++ Builder очень давно не работал, поэтому в каких-то деталях могу быть неточным.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

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

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.