通过终端接收3个文件,并使用fstream将file2和file3的内容连接到file1

时间:2019-04-03 17:21:38

标签: c++

我是C ++的初学者,抱歉,我的代码部分可能没有意义。

我要做的是(C ++,Linux,通过fstream):

·接收终端通过以下方式传递的3个或更多文件:   ./executable file1.txt file2.txt file3.txt

·编写了一个函数,该函数读取文件file2.txt和file3.txt并将其复制到file1.txt(连接,请勿覆盖)

我不知道该怎么做,我对fstream一无所知,我现在只是一个人学习,所以我真的需要帮助。也许在SO中解决了类似的问题,但我不知道如何用它们解决我的问题。

我附上我拥有的代码。我不知道该函数的代码,所以它是空的。

非常感谢您。

我尝试做:

void concat(char *argv[], int numberoffilesreceived){

    char c;

    towritethefiles.open(argv[0], ios::app);

    for(int i=1; i<numberoffilesreceived; i++){
        toreadthefiles.open(argv[i], ios::in);
        while(!toreadthefiles.eof()){
            toreadthefiles >> c;
            towritethefiles<< c;
        }
    }
}

它可以编译但不起作用,程序在运行时会冻结。

我也尝试使用std :: copy,因为我不了解它是如何工作的。

ifstream toreadthefiles;
ofstream towritethefiles;

void concat(char *argv[], int numberoffilesreceived);

int main(int argc, char *argv[]){

    /* 1/2 The code from below to 2/2 it's only to prevent path errors when receiving the files (it works fine) */
    const char directory[SIZE]="./";
    int count_files=0;
    char files[SIZE][SIZE];
    for(int i=1; i<argc; i++){
        strcpy(files[i], directory);
        strcat(files[i], argv[i]);
        count_files++;
    }
    /*2/2 to add ./ to the name files when passed by terminal: ./executable ./file1.txt ./file2.txt ./file3.txt */

    /*check if received almost 3 files like required */
    if(argc<3){
        cout<< "Error, to few files entered" << endl;
        getchar();
        exit(1);
    }

    /*pass the files to the concat function*/
    for(int i=1; i<argc; i++){  
        concat(&argv[i], count_files);      
    }


    toreadthefiles.close();
    towritethefiles.close();

    return 0;
}

void concat(char *argv[], int count_files){

}

2 个答案:

答案 0 :(得分:1)

您可以将std::copy与流迭代器一起使用,并且我已经修正了以前的怀疑,即它会很慢,因此这是一种仅对代码中的注释执行操作的方法。

#include <iostream>
#include <fstream>
#include <vector>
#include <ios>
#include <stdexcept>

void concat(const std::string& destination, const std::vector<std::string>& sources) {
    // open the destination file and keep it open until all is done
    std::ofstream dest_fs(destination, std::ios_base::binary);
    if(!dest_fs) 
        throw std::runtime_error("Could not write to \"" + destination + "\".");

    // loop over the source files
    for(const auto& source_file : sources) {
        // open the current source file
        std::ifstream source_fs(source_file, std::ios_base::binary);
        if(!source_fs)
            throw std::runtime_error("Could not read from \"" + source_file + "\".");

        // copy from source to destination
        std::copy(std::istreambuf_iterator<char>(source_fs),
                  std::istreambuf_iterator<char>(),
                  std::ostreambuf_iterator<char>(dest_fs));
    }
}

int cppmain(std::string program, std::vector<std::string> args) {
    if(args.size() < 2) {
        std::cout << "USAGE: " << program << " destination_file input_file(s)\n";
        return 1;
    }

    // extract the first argument which is the destination file
    std::string destination_file = std::move(args.front());
    args.erase(args.begin()); // erase first argument from the vector

    try {
        // do the concatenation
        concat(destination_file, args);
        return 0;
    } catch(const std::exception& ex) {
        std::cerr << program << ": ERROR: " << ex.what() << "\n";
        return 1;
    }
}

int main(int argc, char* argv[]) {
    return cppmain(argv[0], {argv + 1, argv + argc});
}

答案 1 :(得分:1)

我认为您的DECLARE @strColumns varchar(max) = '' SELECT @strColumns = COALESCE(@strColumns + ',', '') + A.TableName + '.' + QuoteName(Column_Name) + ' AS ' + A.Alies FROM ( SELECT Column_Name, 'Agente' TableName, 'Agente_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Agente' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'Cte' TableName, 'Cte_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Cte' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'CteEnviarA' TableName, 'CteEnviarA_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'CteEnviarA' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'Unidad' TableName, 'Unidad_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Unidad' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'Venta' TableName, 'Venta_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Venta' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'VentaD' TableName, 'VentaD_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'VentaD' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'Art' TableName, 'Art_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Art' AND DATA_TYPE != 'timestamp' UNION ALL SELECT Column_Name, 'Alm' TableName, 'Alm_' + QuoteName(Column_Name) AS Alies FROM INFORMATION_SCHEMA.COLUMNS WHERE Table_Name = 'Alm' AND DATA_TYPE != 'timestamp' ) AS A SELECT @strColumns =SUBSTRING(@strColumns,2, len(@strColumns) - 1) SELECT @strColumns EXEC( 'SELECT '+ @strColumns +' INTO ##temp FROM dbo.Agente FULL JOIN dbo.Cte ON dbo.Agente.Agente = dbo.Cte.Agente FULL JOIN dbo.CteEnviarA ON dbo.Agente.Agente = dbo.CteEnviarA.Agente FULL JOIN dbo.Unidad ON dbo.CteEnviarA.Unidad = dbo.Unidad.Unidad FULL JOIN dbo.Venta ON dbo.Agente.Agente = dbo.Venta.Agente FULL JOIN dbo.VentaD ON dbo.Agente.Agente = dbo.VentaD.Agente FULL JOIN dbo.Art ON dbo.VentaD.Articulo = dbo.Art.Articulo FULL JOIN dbo.Alm ON dbo.Venta.Almacen = dbo.Alm.Almacen') SELECT * FROM ##temp DROP TABLE ##temp 函数存在问题。您正在为传入的每个文件调用concat()。然后在函数中,您使用concat()再次针对输入的文件数运行该循环。

我会考虑重写count_files函数,使其看起来像这样:

concat()

好处是您可以重复使用将单个输入文件附加到现有输出流中的功能,并包装检查以确保文件存在(您可能需要更复杂的功能,例如在要添加的文件上返回true / false,或引发错误等)。

void concat(std::ofstream& outputStream, char* fileToAppend) { std::ifstream in(fileToAppend); if (!in) { cout << "Error, cannot open file: " << fileToAppend; return; } // Use std::getline to read each line in the input stream, // then write it to the output stream! string line; while (std::getline(in, line)) { outputStream << line; } } 中,检查至少三个文件后,将代码替换为:

main()