2014-08-27 39 views
1

我有一个这样的内容的文本文件:Bill, 89 Alex, 64 Dan, 29,它代表一些学生的名字和他们的笔记。
我想对它们进行排序受注升,我的想法是让一个整数,每名,例如:int dan = 29;因此,进一步的,我可以对它们进行排序,但我不知道如何分配用于从文本这个名称的整数文件。
希望你能帮忙,因为这是我第一次制作一些更复杂的程序。谢谢!如何为txt文件中的每个名称创建一个整数?

+0

你的名字是数据,而不是代码。 – 2014-08-27 14:32:08

+3

按什么排序?名称?注意? – 2014-08-27 14:32:11

+0

我想按照说明对它们进行排序,这就是为什么我想让它们整数 – AvramPop 2014-08-27 14:34:41

回答

5

这里的问题是,在C++(如C)中,你必须定义在编译时,即当你写的所有的变量你的代码。在你的例子中,你有任意数量的行的文本文件,所以当你编写代码时,你不知道它的内容。这就是为什么你不能为你的文件的每一行都拥有自己的变量。 因此,如果您需要将文件的每行都存储信息,则可以执行此操作。首先,定义将存储信息(即名称+整数的字符串)的格式。这是你最有可能需要的地方struct或类似的东西。 structclass是在一个结构中聚合不同变量的方法(实质上,它们不仅仅是这一点,但那不是那个时刻的要点)。如果你写了类似

struct Data { 
    std::string name; 
    int ratio; 
}; 

这意味着你刚才定义的数据类型称为数据,有字段“名称”和“比率”。所以,你可以使用它像这样:

Data d; 
d.name = "Ben"; 
d.ratio = 42; 

在此之后,你需要一些实体,可以让你存储许多本数据条目。例如,你可以使用数组。试想一下,你将在这里使用静态数组:

const std::size_t lineCount = getLineCount(); 
Data data_array[lineCount]; //Will not compile, since you cannot use variables as static arrays's size 
for(std::size_t i = 0; i < lineCount; ++i) { 
    data_array[i].name = readName(); 
    data_array[i].ratio = readRatio(); 
} 

问题就在这里,你可以看到,就是你无法知道你的文本文件的行数,当你写的代码。所以,你可以在你的动态数组与此代码:

const std::size_t lineCount = getLineCount(); 
Data* data_array = new Data[lineCount]; 
for(std::size_t i = 0; i < lineCount; ++i) { 
    data_array[i].name = readName(); 
    data_array[i].ratio = readRatio(); 
} 
delete[] data_array; 

这将工作,只要你总算知道行数,如果之前实际的工作文件完成,这不是通常的地步。

另外原始的动态数组并不真的很好用,因为你必须担心新的/删除函数对。所以,在这里,来自Standart Template Library的课程叫做容器。这些类为您提供插入数据的方式,并以多种方式处理这些数据。这是类“map”,“unordered_map”,“multimap”,“矢量”和其他来自以前的答案。他们最容易理解的就是矢量,你可以阅读它here。其他人(比如说,map)应该更适合你的任务。

最后,要对这些数据的数组(或容器)进行排序,您可以使用来自Standart Template Library的称为算法的函数。它们提供通用的方式来以您需要的方式操作数据。 您可以阅读更多here

不确定我需要在这里多说,探索链接,继续学习,祝你好运!

+0

谢谢!它会工作 – AvramPop 2014-08-27 16:40:03

+0

我想问你一些更多的东西:我现在如何实现从文件读入该代码,因为你刚刚告诉我主要算法。我想知道如何将它连接到.txt文件... – AvramPop 2014-08-28 10:09:52

+0

@ Issue429那么,正如你在下面的评论中所说的,你已经学会了使用文本文件。有两种主要的方法可以做到这一点:C语言本身提供[FILE](http://www.cplusplus.com/reference/cstdio/FILE/)处理对象和函数来处理它。 C++引入了名为[stream]的面向对象方法(http://www.cplusplus.com/reference/iostream/)。使用你的老师(如果有的话)希望你使用。链接可能会帮助你调查更多。 – prez 2014-08-28 11:09:35

0

使用std::unordered_map<string, int>

//用法:

std::unordered_map<string, int> content; 
//open file; 
while(/*not end of file*/){ 
    std::string name; 
    int mark; 
    file>>name>>mark; 
    name.erase(name.end()-1); 
    content[name]=mark; 
} 
//close file; 
+0

为什么无序?他希望他们排序。 – 2014-08-27 14:31:27

+0

'map'和'unordered_map'有什么区别? – GingerPlusPlus 2014-08-27 14:32:46

+0

'map' ...命令它的元素。嘿。最常用的是一个RB树,而'unordered_map'是一个散列表。 – Quentin 2014-08-27 14:33:44

2

有可能是一个更聪明的方式来做到这一点,但因为你是一个初学者,这里是我的建议:

使用std::multimap<int, std::string>作为一个查找表给出int注释的名称(存储为std::string)。如果某些名称具有相同的值int,您需要std::multimap而不是std::map。另外,存储所有号码在std::vector<int>并调用std::sort()std::vector<int>排序。现在他们已经排序了,您可以使用std::multimap::find()来查找与每个int值相关联的名称。

+3

简单地迭代multimap应该按顺序给出笔记,不是吗? “关联容器迭代器的基本属性是它们按键的非降序顺序迭代容器,其中非降序由用于构造它们的比较定义。” – 2014-08-27 15:15:23

+0

是的,好点。 – Null 2014-08-27 15:25:04

0
struct name_and_mark{ 
    std::string name; 
    int mark; 
    bool operator<(name_and_mark &second){ 
     return mark<second.mark; 
    } 
}; 

std::istream& operator>>(std::istream &stream, name_and_mark &data){ 
    stream>>data.name>>data.mark; 
    data.name.erase(data.name.end()-1); 
    return stream; 
} 

std::forward_list<name_and_mark> content; 
//open file; 
while(/*not end of file*/){ 
    name_and_mark temp; 
    file>>temp; 
    content.push_front(temp); 
} 
//close file; 
content.sort(); 

//检查出来:

std::ostream& operator<<(std::ostream &stream, name_and_mark &data){ 
    stream<<data.name<<", "<<data.mark<<'\n'; 
    return stream; 
} 

for(auto &i:content) 
    std::cout<<i; 
+0

因为我开始使用命名空间std,那是std有用吗? – AvramPop 2014-08-27 15:08:08

+0

当您在此代码之前编写'using namespace std'时,可以跳过每个'std ::'。 – GingerPlusPlus 2014-08-27 15:09:24

+0

最后的陈述是做什么的? – AvramPop 2014-08-27 15:27:38

相关问题