3

我正在为我的 c++ 类制作一个程序。最终,我希望我的程序对以下格式的联系人文本文件执行快速排序:

名字 名字 号码

每个联系人由一个新行分隔。我首先计算行数并使用动态内存分配来创建一个与行数具有相同大小的结构数组。

但是,当我尝试从文本文件中读取信息并将其输出到屏幕时,我得到的只是乱码。我在互联网上四处寻找解决方案,但我发现的所有内容似乎都使用了不同的语法。

到目前为止,这是我的代码:

#include <iostream>
#include <fstream>
#include <istream>

char in[20];
char out[20];

using namespace std;

struct contact
{
    char firstName[14];
    char surName[14];
    char number[9];
};
//structure definition

int main(void){

    cout << "Please enter the input filename: " << endl;
    cin >> in;
    ifstream input(in);

    if(!input){
        cerr << "failed to open input file " << in << endl;
        exit(1);
    }

    cout << "Please enter tne output filename: " << endl;
    cin >> out;

    // read in the input and output filenames

    char a;
    int b=0;
    while (input.good ())
    {
        a=input.get ();
        if (a=='\n')
        {
            b++;
        }
    }
    // count the number of lines in the input file

    input.seekg (0, ios::beg);

    //rewind to beginning of file

    contact* list = new contact[b];

    //dynamically create memory space for array of contacts

    int i = 0.;
      while(input){
            if(i >= b) break;
            if(input >> *list[i].firstName >> *list[i].surName >> *list[i].number) i++;  
            else break;
      }
    input.close();

    //read information from input file into array of contacts

    for(int N = 0; N < b; N++){
        cout << list[N].firstName << list[N].surName << list[N].number << endl;
    }

    ofstream output(out);
    int k = 0;
    for(int k = 0; k<b; k++){
        output << list[k].firstName << "        " << list[k].surName << "       " << list[k].number << endl;
    }

    //print out the unsorted list to screen and write to output file
    //i've done both here just to check, won't print to screen in final version

    output.close();
    delete []list;

}       // end of main()
4

2 回答 2

0

Okay, I put together a quick and dirty method using newer C++ constructs to get you most of the way there. You're on your own for writing to the file (trivial) and the quicksort, though I've put the struct into a vector for you, so sorting the vector is as easy as writing a custom function to compare one struct vs the other. I apologize in advance if some of the code is less than canonical C++. I'm way past my bed time, and way tired, but this was interesting enough of a problem that I wanted to give it a go. Happy coding!

#include <iostream>
#include <fstream>
#include <istream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
#include <sstream>

using namespace std;

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

struct contact
{
    std::string firstName;
    std::string surName;
    std::string number;

    contact(std::string& fName, std::string& lName, std::string& num) : firstName(fName), surName(lName), number(num) {}
};
//structure definition

char in[20];
char out[20];

int main()
{
    std::vector<contact> contacts;

    cout << "Please enter the input filename: " << endl;
    cin >> in;
    ifstream input(in);

    if(!input){
        cerr << "failed to open input file " << in << endl;
        exit(1);
    }

    cout << "Please enter tne output filename: " << endl;
    cin >> out;

    std::string sinput;

    // read in the input and output filenames
    while (input.good ())
    {
        getline(input, sinput);

        vector<string> tokens = split(sinput, ' ');
        if (tokens.size() == 3)
        {
            contact c(tokens[0], tokens[1], tokens[2]);
            contacts.push_back(c);
        }
    }

    input.close();

    //read information from input file into array of contacts

    std::cout << "Outputting from vector..." << std::endl;
    for_each(contacts.begin(), contacts.end(), [](contact& c) {
        cout << c.firstName << " " << c.surName << " " << c.number << endl;
    });

    return 0;
}

Also, just want to give credit that the split methods come from this answer on this very site. Cheers!

于 2012-12-11T04:12:04.923 回答
0

您将文件位置重置为开头,但从您第一次读取行数时开始,文件 eofbit 仍被标记为 true。快速解决此问题的方法是在读取行后重新打开文件,可能使行数成为清理代码的函数。

int lines(const string path)
{
    ifstream tmp(path.c_str());
    string temp;
    int count = 0;
    getline(inFile,temp);
    while(inFile)
    {
       count++;
       getline(inFile,temp);
    }
    tmp.close();
    return count;
}
于 2012-12-11T01:44:30.050 回答