我是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){
}
答案 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()