在c++中使用fstream写入输出文件

Writing to an output file using fstream in C++

本文关键字:输出 文件 fstream c++      更新时间:2023-10-16

假设您有正确的头,并使用命名空间std;在使用fstream将字符串输出到某些输出文件方面,这是否有些正确?我只包含了代码中相关的文件API部分,因为整个代码太长了。我已经包含了iostream和fstream头文件。然而,我似乎得到一些特定的错误,与我使用myfile类或对象的方式。

#include <curses.h>
#include <math.h>
#include "fmttime.h"
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>                      // Needed for the file API
#include <iostream>                     // File API headers for C++
#include <fstream>
using namespace std;
// Enumeration list for the colors of the grid, title, sin and cos waves
enum colors
{
        Gridcolor = 1,
        Titlecolor,
        Sincolor,
        Coscolor,
};
void Sim_Advance(int degrees);          // Function prototype for Phase angle
double Sim_Cos();                       // Function that calculates cos
double Sim_Sin();                       // Function that calculates Sin
char* usage();                          // Function which returns error mssg
static const double PI = (M_PI/180);    // Degrees to radian factor
static double PA = 0;                   // Phase angle
static double x;                        // X dimension of screen
static double y;                        // Y dimension of screen
static int delay1 = 300000;             // 300ms Delay
static int currenty = 0;                // Y index
static const int buffsize = 25;         // Size of the character buffer for time
// Function prototype for frame of plot function
void frame(const char* title, int gridcolor, int labelcolor);
// Function prototype for the symbols that form the plot
void mark(WINDOW* window, char ch, int color, double value);
int main(
        int argc,                       // Number of command line arguements
        char* argv[]                    // String of each command line
        )
{
    initscr();                          // Curses.h initilizations
    cbreak();
    nodelay(stdscr, TRUE);
    noecho();                           // Supress character inputs on screen
    start_color();                      // Enable Bg/Fg colors
    // Color Initializations for the enumeration list
    init_pair(Gridcolor, COLOR_RED, COLOR_BLACK);
    init_pair(Titlecolor, COLOR_GREEN, COLOR_BLACK);
    init_pair(Sincolor, COLOR_YELLOW, COLOR_BLACK);
    init_pair(Coscolor, COLOR_MAGENTA, COLOR_BLACK);

    int keyhit;                         // Holder for the getch command
    int ctr = 1;                        // Exit flag
    int degrees = 10;                   // Interval to be added to phase
    int enablelog = 0;                  // Flag for Logging enable
    int disabletrunc = 0;               // Flag for logging without truncation
    char* outputName = NULL;            // Name of output program
    FILE* pLog;                         // File pointer for O/P write
    getmaxyx(stdscr,y,x);               // Find max x and y values of stdscrn
    // Defining a new window in the terminal for printing the plot
    WINDOW* Window = newwin(y-4, x, 2, 0);
    x = x - 2 - buffsize;               // Move window to allow for timestamp
    scrollok(Window, TRUE);             // Enable scrolling window
    // Title string for the plotter
    char cTitle[] = {"Real time Sine/ Cosine Plot"};
    //  API Code for FILE output
    ofstream myfile (pLog);             //
    int i = 1;                          // Index for how many times getopt needs
                                        // to be called. Starts at 1 to offset
                                        // program call string, without options
    while (i < argc)
    {
        switch (getopt (argc, argv, "ao:"))
        {
                case 'a':
                disabletrunc = 1;
                break;
                case 'o':
                enablelog = 1;
                outputName = optarg;    // Gets the name of textfile
                // Open the file as designated by the user
                // and assign it to the file pointer pLog
                // The following if else statement opens the file for
                // logging in 2 distinct modes, extended and truncation
                if (disabletrunc == 1)
                {
                    pLog = myfile.open (outputName, ios::out | ios::app);
                }
                else
                {
                // Print with truncation
                    pLog = myfile.open (outputName, ios::out | ios::trunc);
                }
                break;
                // Case of error, print usage message
                case '?':
                endwin();
                puts(usage());
                return 0;
                break;
                // No more options on command line
                case -1:
                i = argc;
                break;
        }
        ++i;
    }
    // If only '-a' is enabled then this is still an error case
    // This if statement handles that case
    if (disabletrunc == 1 && enablelog == 0)
    {
        endwin();
        puts("nWARNING: -a must be used in conjuction with -o FILENAME");
        puts(usage());
        return 0;
    }

        while (ctr == 1)                // This will run the program till
        {                               // exit is detected (CTRL-X)
            usleep(300000);             // Delays program execution
            keyhit = getch();
            frame(cTitle, Gridcolor, Titlecolor);  // Prints out the frame once
           struct timeval tv;
            char buf[buffsize];                    // Buffer being sent to formattime
            gettimeofday(&tv, NULL);               // calling function for epoch time
            formatTime(&tv, buf, buffsize);        // Calling formaTime for timestamp
            wattrset(Window, COLOR_PAIR(Gridcolor));
            wprintw(Window,"%s", buf);
            wrefresh(Window);
            mark(Window,'|', Gridcolor, 0);
            mark(Window,'C', Coscolor, Sim_Cos());
            mark(Window,'S', Sincolor, Sim_Sin());
            // Scroll to next y coordinate
            wmove(Window, currenty, buffsize + x);
            wrefresh(Window);
            wprintw(Window, "n");
            wrefresh(Window);
            currenty = getcury(Window);

            // Print desired data into the output file
            if (enablelog == 1)
                myfile << buf << Sim_Sin() << Sim_Cos() << endl;
                //fprintf(pLog, "%s, %f, %fn", buf, Sim_Sin(), Sim_Cos());
            Sim_Advance(degrees);       // Advances PA by "degrees" value (10)

                if (keyhit == 24)
                {
                    ctr = 0;            // Exit flag set
                }
        }
        // Only close the file if file exists to avoid error
        if (enablelog == 1)
        {
            myfile.close(pLog);
            //close(pLog);
        }
    endwin();
    return 0;
}
// This function will provide an usage message and give the user
// a list of acceptable option characters to use with the program
// when a non valid option character is used or used improperly
char* usage()
{
    // String to be printed as the error message
    static char errors[] = {"nSorry Invalid Option enterednn"
                            "Please Enter a Valid Option specifier:n"
                            "-o FILENAME      Enable logging to specified "
                            "output file: FILENAMEn"
                            "-a          Enable extended logging"
                            " rather than truncated loggingnn"
                            "Please Note: -a cannot be used without -o"
                            " FILENAMEn"};
    return errors;
}

然后打印到文件中,我可以这样做吗?

myfile << buf << Sim_Sin() << Sim_Cos() << endl;
myfile.close(pLog);

Sim_Sin()和Sim_Cos()返回双精度值,而buf只是一个格式化字符串。我试着在互联网上应用一些资源,但它似乎不同意我的实现(这显然是错误的)。

以下是错误

plot.cc: In function 'int main(int, char**)':
plot.cc:93: error: no matching function for call to 'std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(FILE*&)'
/usr/include/c++/4.4/fstream:623: note: candidates are: std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.4/fstream:608: note:                 std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.4/iosfwd:84: note:                 std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(const std::basic_ofstream<char, std::char_traits<char> >&)
plot.cc:117: error: expected ';' before 'pLog'
plot.cc:124: error: void value not ignored as it ought to be
plot.cc:208: error: no matching function for call to 'std::basic_ofstream<char, std::char_traits<char> >::close(FILE*&)'
/usr/include/c++/4.4/fstream:736: note: candidates are: void std::basic_ofstream<_CharT, _Traits>::close() [with _CharT = char, _Traits = std::char_traits<char>]

这几乎肯定是正确的

目前,我将忽略其他问题,处理写作本身。写作本身最明显的问题是,您几乎总是希望一些将一个值与下一个值分开。它可以是空格、逗号、制表符、换行符……,但你需要一些东西。没有这个,基本上不可能弄清楚哪个数字属于哪个数字——例如:1234.56789.876

因此,在写出数据时,您希望在信息片段之间放置一些可识别的东西:

myfile << buf << "t" << Sim_Sin() << "t" <<  Sim_Cos() << endl;
第二,endl 几乎是不理想的。许多人(大多数?)认为它只是在输出中添加了一个新行,但它也刷新了流。只要你只写一两行数据,这可能无关紧要,但如果你写很多数据,它可能会大大降低你的代码速度。
myfile << buf << "t" << Sim_Sin() << "t" <<  Sim_Cos() << "n";

在相对罕见的情况下,您确实想要刷新流,我建议使用std::flush来明确该意图。

编辑:编辑后,似乎您还试图将iostreams与c风格的FILE * s混合(例如,试图打开一个流,但提供c风格的FILE *作为参数)。我通常建议选择c风格的FILE *(如果你没有选择的话)或iostreams(如果可能的话),并始终坚持使用它。像您这样将两者混合在一起不仅会导致很多混乱,而且在某些情况下还会减慢您的代码速度(额外的时间来保持两者协调)。

std::ofstream myfile("name.txt");
myfile << buf << "t" << Sim_Sin() << "t" <<  Sim_Cos() << "n";