用于对文本文件进行排序的 C++ 代码不起作用

标签 c++ sorting csv

一位 friend 给我留下了一个代码,它应该打开 2 个文件 solution.txtpriority.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.txtname(s) 和关联的value(s) 按priority 定义的顺序放置。 .csv
  • 创建一个数组,其中包含的列数与颜色数一样多,行数与 solution.txt
  • 中的一样多
  • 用与每个 linecolorname 关联的 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++ 中使用 newdelete。所以不要使用 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/

相关文章:

C++ 没有合适的默认构造函数可用 - 继承的模板化构造函数没有参数

c++ - 初始化 const 类成员,错误 : declaration does not declare anything

c++ - 使用 Hoare 分区方案的快速排序算法返回原始未排序列表

arrays - 如何使用合并排序算法进行就地排序?

java - Java 中 TSV 文件的验证

c++ - 如何在 C++ 中将数组类型衰减为 const 指针类型?

c++ - 为什么不能用 C++ 中的一个新调用来分配多维数组?

java - Elasticsearch : Sorting by nested documents' values

python - 在Python中按两列对数据框进行排序

node.js - 在 CSV 中使用 Node js 写入匹配的行