一位 friend 给我留下了一个代码,它应该打开 2 个文件 solution.txt
和 priority.csv
并生成第三个文件 result.txt
作为输出。
文件结构:
solution.txt
包含由逗号分隔的目标、名称和值的有序列表,我知道该文件包含多少行:
target0,name0,value0,name1,value1,name2,value2,name3,value3 target1,name4,value4,name5,value5,name6,value6,name7,value7 target2,name8,value8,name9,value9,name10,value10,name11,value11 ...etc
- 一些
solution.txt
的行只包含一个target
值:
target3
target4
target5 ...etc.
priority.csv
包含颜色名称的索引列表,我知道有多少颜色名称:
1,colorname1
2,colorname2
3,colorname3
下面的代码应该执行以下操作:
- 询问solution.txt包含多少行数据
- 询问
priority.csv
中包含多少个colornames - 将
solution.txt
的name
(s) 和关联的value
(s) 按priority 定义的顺序放置。 .csv
- 创建一个数组,其中包含的列数与颜色数一样多,行数与
solution.txt
中的一样多
- 用与每个
line
和colorname
关联的value
填充此数组 - 其他情况填0
由于某些我不明白的原因,该代码无法正常工作。如果你有勇气编译它,这里有例子放在 solution.txt 和 priority.txt 中:
解决方案.txt
99985,CIN,0.624049619347,OR0,0.36925123875,K2M,0.00387491644559,gY6D,0.00282422545715
99986,CIN,0.624372658354,OR0,0.369683600811,K2M,0.00365124527159,gY6D,0.00229249556329
99987,CIN,0.624695697361,OR0,0.370115962872,K2M,0.0034275740976,gY6D,0.00176076566943
99988,CIN,0.625018736368,OR0,0.370548324933,K2M,0.0032039029236,gY6D,0.00122903577557
99989,CIN,0.625341775375,OR0,0.370980686994,K2M,0.00298023174961,gY6D,0.00069730588171
99990,CIN,0.625664814382,OR0,0.371413049055,K2M,0.00275656057561,gY6D,0.000165575987851
优先级.csv
1,CIN
2,K2M
3,gY6D
4,OR0
在这个例子中,线的数量是 6,有 4 种颜色
这就是代码,我列出了可能的错误,并在控制台上打印了 error2 和 error4:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>
using namespace std;
int main() {
int COLORS = 0;
int LINES = 0;
cout << endl << "Original Data (solution.txt):" << endl << endl << "How many lines?" << endl;
cin >> LINES;
cout << "How many colors in the list?" << endl;
cin >> COLORS;
char Coul[COLORS][LINES];
//1- reading the file priority.csv
for (int i=0; i<COLORS; i++) Coul[i][0]='\0';
FILE *Read=fopen("priority.csv","rt");
if (Read == NULL) {
printf("Error 1");
return(0);
}
char line[120];
int N;
for (int i=0; i<COLORS; i++)
{
char name[8];
fgets(line,15,Read);
sscanf(line,"%d,%s",&N,name);
if (N == i) strcpy(Coul[i], name);
else {
printf("Error 2"); // Error2
break;
}
}
fclose(Read);
//2- reading the file solution.txt and writing the result.
Read=fopen("solution.txt","rt");
if (Read == NULL) {
printf("Error 3"); // Error3
return(0);
}
FILE *Write=fopen("result.txt","wt");
for (int i=1; i<LINES; i++)
{
char c[4][8]; // 4 color names
float v[4]; // 4 values
fgets(line,119,Read);
sscanf(line,"%d,%s,%f,%s,%f,%s,%f,%s,%f",
&N, c[0], &v[0], c[1], &v[1], c[2], &v[2], c[3], &v[3]);
if (N == i)
{
if (strlen(c[0]) == 0) // the line is empty
{
fprintf(Write,"%d ",i);
for (int i=0; i<COLORS; i++) fprintf(Write,"0 ");
fprintf(Write,"\n");
}
else
{
fprintf(Write,"%d ",i);
int r[4];
// we search the rang of c[ordre]
for (int order=0; order<4; order++)
{
for (int ir=0; ir<COLORS; ir++)
{
if (strcmp(c[order], Coul[ir]) == 0) r[order]=ir;
}
}
for (int ir=0; ir<r[0]; ir++) fprintf(Write,"0 ");
fprintf(Write,"%d ",v[0]);
for (int ir=r[0]+1; ir<r[1]; ir++) fprintf(Write,"0 ");
fprintf(Write,"%d ",v[1]);
for (int ir=r[1]+1; ir<r[2]; ir++) fprintf(Write,"0 ");
fprintf(Write,"%d ",v[2]);
for (int ir=r[2]+1; ir<r[3]; ir++) fprintf(Write,"0 ");
fprintf(Write,"%d ",v[3]);
for (int ir=r[3]+1; ir<57; ir++) fprintf(Write,"0 ");
fprintf(Write,"\n");
}
}
else {
printf("Error 4");
break;
} //Error4
}
fclose(Write);
fclose(Read);
}
可以帮忙调试吗?我迷路了! 阿德里安
最佳答案
因为你想动态分配内存,你必须在 C++ 中使用 new
和 delete
。所以不要使用 char Coul[COLORS][LINES];
使用这些行:
char **Coul = NULL;
Coul = new char*[COLORS];
for(int i = 0; i < COLORS; i++)
Coul[i] = new char[LINES];
最后添加这些:
for(int i = 0; i < COLORS; i++)
delete [] Coul[i];
delete [] Coul;
它应该可以编译,但我无法通过 &N
部分,因为我无法理解您要做什么。
编辑: 完成!
编辑2: 如果我假设打开文件不会将其全部加载到 RAM 中是正确的,那么下面是适用于旧代码的 RAM 友好代码,它使用临时文件作为缓冲区(它可能有点慢,你需要更多的磁盘空间)。
编辑3: 将可能不安全的 string._Copy_s() 更改为新发现的 string.substr()
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
using namespace std;
class Sorter
{
private:
bool save_RAM, temp1_cleared, temp2_cleared;
string temp1, temp2;
int COLORS, LINES;
string *Color_codes, **Color_values;
bool find_codename(string line, string codename)
{
if (line.find(codename) == -1)
return 0;
else
{ //checking if there are other letters, which would make this codename not full and incorrect
char a, b;
if (line.find(codename) == 0)
{
b = line[codename.length()];
if (b == ',')
return 1;
else
return 0;
}
else
{
a = line[line.find(codename) - 1];
b = line[line.find(codename) + codename.length()];
if (a == ',' && b == ',')
return 1;
else
return 0;
}
}
}
void allocate_memory()
{
if (!save_RAM)
{
Color_codes = new string[COLORS];
Color_values = new string*[LINES];
for (int i = 0; i < LINES; i++)
Color_values[i] = new string[COLORS];
}
}
void deallocate_memory()
{
if (!save_RAM)
{
delete [] Color_codes;
for (int i = 0; i < LINES; i++)
delete [] Color_values[i];
delete [] Color_values;
}
else
{
remove(temp1.c_str());
remove(temp2.c_str());
}
}
void clear_temporary_file(const char *filename, bool &was_cleared)
{
if (was_cleared)
return;
else
was_cleared = true;
ofstream temp_file(filename);
if (temp_file == NULL)
{
cout << "Error 6";
cin.get();
exit(EXIT_FAILURE);
}
temp_file.close();
}
void write_to_temporary_file(const char *filename, string value)
{
ofstream temp_file(filename, ios::app);
if (temp_file == NULL)
{
cout << "Error 5";
cin.get();
exit(EXIT_FAILURE);
}
temp_file << value << endl;
temp_file.close();
}
string read_line(const char *filename, int line_number, bool twoD_array, int second_line_number, int line_length)
{
ifstream temp_file(filename);
string line;
if (temp_file == NULL)
{
cout << "Error 7";
cin.get();
exit(EXIT_FAILURE);
}
if (!twoD_array)
{
for (int i = 0; i < line_number; i++)
getline(temp_file, line);
getline(temp_file, line);
}
else
{
for (int j = 0; j < second_line_number + (line_length*line_number); j++)
getline(temp_file, line);
getline(temp_file, line);
}
temp_file.close();
return line;
}
void seperate_input(string line, int &N, string &Name)
{
string temp;
stringstream tempbuf;
line += ',';
stringstream ss(line);
getline(ss, temp, ',');
tempbuf << temp;
tempbuf >> N;
tempbuf = stringstream();
getline(ss, temp);
tempbuf << temp;
tempbuf >> Name;
}
void Generate_values(int line_number, string Other_stuff)
{
string temp;
if (!save_RAM)
{
for (int i = 0; i < COLORS; i++)
{
if (find_codename(Other_stuff, Color_codes[i]))
{
int j = 0;
bool search = true;
int a, b; //find comma positions
a = Other_stuff.find(Color_codes[i]) + Color_codes[i].length() + 1;
while(search)
{
j++;
char c = Other_stuff[a + j];
if (c == ',')
{
b = a + j;
search = false;
}
}
temp = Other_stuff.substr(a, b); // copy value to temporary buffer
Color_values[line_number][i] = temp;
}
else
Color_values[line_number][i] = "0";
}
}
else
{
clear_temporary_file(temp2.c_str(), temp2_cleared);
for (int i = 0; i < COLORS; i++)
{
string codename = read_line(temp1.c_str(), i, false, 0, 0);
if (find_codename(Other_stuff, codename))
{
int j = 0;
bool search = true;
int a, b; //find comma positions
a = Other_stuff.find(codename) + codename.length() + 1;
while(search)
{
j++;
char c = Other_stuff[a + j];
if (c == ',')
{
b = a + j;
search = false;
}
}
temp = Other_stuff.substr(a, b); // copy value to temporary buffer
write_to_temporary_file(temp2.c_str(), temp);
}
else
write_to_temporary_file(temp2.c_str(), "0");
}
}
}
double convert_to_double(string number)
{
double also_number = 0;
stringstream ss(number);
ss >> also_number;
return also_number;
}
public:
Sorter(bool RAM_saver)
{
COLORS = 0;
LINES = 0;
Color_codes = NULL;
Color_values = NULL;
save_RAM = RAM_saver;
temp1 = "temp_code.txt";
temp2 = "temp_values.txt";
temp1_cleared = false;
temp2_cleared = false;
}
~Sorter()
{
deallocate_memory();
}
void get_user_input()
{
cout << endl << "Original Data (solution.txt):" << endl << endl << "How many lines?" << endl;
while (!(cin >> LINES))
{
cin.clear();
cin.sync();
}
cout << "How many colors in the list?" << endl;
while (!(cin >> COLORS))
{
cin.clear();
cin.sync();
}
allocate_memory();
}
void read_priority_file(const char *filename)
{
ifstream priority_file(filename);
if (priority_file == NULL)
{
cout << "Error 1";
cin.get();
exit(EXIT_FAILURE);
}
string line;
int N;
if (!save_RAM)
{
for (int i = 0; i < COLORS; i++)
{
string Name;
getline(priority_file, line);
seperate_input(line, N, Name);
if (N == (i+1))
{
Name.pop_back(); //push last , out (I need it other function)
Color_codes[i] = Name;
}
else
{
priority_file.close();
cout << "Error 2";
cin.get();
exit(EXIT_FAILURE);
}
}
}
else
{
clear_temporary_file(temp1.c_str(), temp1_cleared);
for (int i = 0; i < COLORS; i++)
{
string Name;
getline(priority_file, line);
seperate_input(line, N, Name);
if (N == (i+1))
{
Name.pop_back(); //push last , out (I need it other function)
write_to_temporary_file(temp1.c_str(), Name);
}
else
{
priority_file.close();
cout << "Error 2";
cin.get();
exit(EXIT_FAILURE);
}
}
}
priority_file.close();
}
void read_solution_and_generate_result(const char *filename)
{
ifstream solution_file(filename);
if (solution_file == NULL)
{
cout << "Error 3";
cin.get();
exit(EXIT_FAILURE);
}
string line;
int N;
for (int i = 0; i < LINES; i++)
{
string Other_stuff;
getline(solution_file, line);
seperate_input(line, N, Other_stuff);
if (N == (i+1))
Generate_values(i, Other_stuff);
else
{
solution_file.close();
cout << "Error 4";
cin.get();
exit(EXIT_FAILURE);
}
}
solution_file.close();
}
void print_results_to_file(const char *filename)
{
ofstream result_file(filename);
if (result_file == NULL)
{
cout << "Error 5";
cin.get();
exit(EXIT_FAILURE);
}
if (!save_RAM)
{
for (int i = 0; i < COLORS; i++)
{
result_file << Color_codes[i];
if (i != COLORS-1)
result_file << ",";
}
}
else
{
for (int i = 0; i < COLORS; i++)
{
result_file << read_line(temp1.c_str(), i, false, 0, 0);
if (i != COLORS-1)
result_file << ",";
}
}
result_file << endl;
if (!save_RAM)
{
for (int i = 0; i < LINES; i++)
{
for (int j = 0; j < COLORS; j++)
{
if (Color_values[i][j] != "0")
{
result_file.setf(ios::fixed);
result_file << setprecision(9) << convert_to_double(Color_values[i][j]);
result_file.unsetf(ios::fixed);
}
else
result_file << convert_to_double(Color_values[i][j]);
if (j != COLORS-1)
result_file << ",";
}
result_file << endl;
}
}
else
{
string value;
for (int i = 0; i < LINES; i++)
{
for (int j = 0; j < COLORS; j++)
{
value = read_line(temp2.c_str(), i, true, j, COLORS);
if (value != "0")
{
result_file.setf(ios::fixed);
result_file << setprecision(9) << convert_to_double(value);
result_file.unsetf(ios::fixed);
}
else
result_file << convert_to_double(value);
if (j != COLORS-1)
result_file << ",";
}
result_file << endl;
}
}
result_file.close();
}
};
int main()
{
bool save_my_RAM = false;
Sorter sort(save_my_RAM);
sort.get_user_input();
sort.read_priority_file("priority.csv");
sort.read_solution_and_generate_result("solution.txt");
sort.print_results_to_file("results.txt");
return 0;
}
关于用于对文本文件进行排序的 C++ 代码不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18125026/