C++ 结构向量的问题:取消迭代器的频率(可能很容易)

C++ 结构向量的问题:取消迭代器的频率(可能很容易),c++,pointers,vector,struct,C++,Pointers,Vector,Struct,我的程序有问题。该程序旨在以逗号分隔的名称形式从文件中获取输入,并在输出文件中对它们进行计数(我还没有得到)。它在“好到目前为止3”之前失败。显然,它的突破之处在于取消了迭代器的功能。也就是说,我要做的是把它当作一个指针,然后把它当作一个指针。这应该跳到数组中的下一个结构。然后,我想使用它->inputName来访问结构内部的某些内容。但是,当我在->inputName中执行此操作时,它尝试将其用作指针,但它无法做到这一点。不知道从这里开始该怎么做,如果我尝试创建一个像name*it这样的常规指

我的程序有问题。该程序旨在以逗号分隔的名称形式从文件中获取输入,并在输出文件中对它们进行计数(我还没有得到)。它在“好到目前为止3”之前失败。显然,它的突破之处在于取消了迭代器的功能。也就是说,我要做的是把它当作一个指针,然后把它当作一个指针。这应该跳到数组中的下一个结构。然后,我想使用它->inputName来访问结构内部的某些内容。但是,当我在->inputName中执行此操作时,它尝试将其用作指针,但它无法做到这一点。不知道从这里开始该怎么做,如果我尝试创建一个像name*it这样的常规指针,它不能与nameStorage.begin()一起工作,因为这只需要一个迭代器。如果有帮助的话,我正在使用Microsoft Visual Studio 2010安装windows 7

我对编程相当陌生,所以任何其他的技巧都会很好。谢谢大家!

#include <iostream>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

struct name{
    int tally;
    string inputName;
};

bool die( const string& message );

int main( void ) {
    ifstream infile;
    infile.open( "input.txt", ifstream::in );

    vector<name> nameStorage; // stores all names and tallies of them
    vector<name>::iterator it;
    string tempInput; // Stores the most recent input temporarily
    char temp;
    int counter = 0;
    while ( temp = infile.get(), infile.good() ) { // loop while extraction from file is possible
        if ( temp != ',' ) {
            tolower ( temp ); // makes everything lowercase
            tempInput.push_back(temp); }
        else {
            cout<<"good so far"<<endl;
            for ( it = nameStorage.begin(); it <= nameStorage.end(); it++ ) {
                cout<<"good so far 2"<<endl;
                if ( tempInput == it->inputName ) { 
                    cout<<"good so far 3"<<endl;
                    it->tally++;
                    break;
                }
                else if ( it == nameStorage.end() ) {
                    name tempStruct;
                    tempStruct.inputName = tempInput;
                    tempStruct.tally = 1;
                    nameStorage.push_back( tempStruct );
                }
            }
            tempInput.clear(); // clears the string after it has stored it
        }
        counter++;
        cout<<"Detected "<<counter<<" characters so far."<<endl;
    }
}

bool die( const string& message ) {
    cerr<<message;
    exit (EXIT_FAILURE);
}
#包括
#包括
#包括
#包括
使用名称空间std;
结构名{
整数计数;
字符串输入名;
};
bool die(常量字符串和消息);
内部主(空){
河流充填;
open(“input.txt”,ifstream::in);
vector nameStorage;//存储所有名称及其计数
向量::迭代器;
字符串tempInput;//临时存储最近的输入
焦炭温度;
int计数器=0;
while(temp=infle.get(),infle.good()){//loop,而从文件中提取是可能的
如果(温度!=','){
tolower(temp);//使所有内容都小写
tempInput.push_back(temp);}
否则{

cout您没有向
名称存储添加任何元素,因此无法迭代该
向量容器的元素。由于您没有在for循环中正确检查向量迭代器的边界,因此它允许您进入循环,并且您正在解引用一个不指向任何元素的迭代器事情。通过尝试访问尚未分配的内存,您调用了未定义的行为,如果内存损坏但未能崩溃,则很可能导致分段错误或其他一些奇怪的问题。

更改:

for ( it = nameStorage.begin(); it <= nameStorage.end(); it++ )
移动:

在现在更改的for循环之外,您不需要else if,因为这是for循环结束的条件:

name tempStruct;
tempStruct.inputName = tempInput;
tempStruct.tally = 1;
nameStorage.push_back( tempStruct );

检查这个简单的例子。

向量的范围是
[begin(),end())
end()
不包括在有效元素的范围内。
end()
指的是一个元素(如果可以调用它)超过
向量的末尾

因此,当
it==nameStorage.end()
时,显然会遇到取消引用迭代器的问题,因为
it
不会引用现有元素:

if ( tempInput == it->inputName )

约定终止于
!=end()
,这将通过上述一个问题消除关闭:

for ( it = X.begin(); it != X.end(); it++ )
迭代器的思想是对内部结构完全隐藏;迭代器的值不一定大于下一个元素的值


在这种情况下,您将少进行一次迭代,并且条件
else if(it==nameStorage.end())
永远不会是真的。但是,您只需在
for
循环之后添加该语句的主体,因为一旦循环终止,您就迭代到
向量的末尾,这段代码至少有4个问题,其中最重要的问题是使用向量进行此类查找/计数效率极低新界


1) std::vector::end()返回一种特殊类型的迭代器,该迭代器不支持布尔运算符,例如添加另一个答案来回答有关映射和std::getline的问题

映射是将键与值关联的关联容器。例如,std::map是一个映射,其键类型为std::string,值类型为int。映射支持快速查找键(log(n))。例如

std::映射名称计数;
是一个将存储与字符串键关联的int值的映射(请参阅std::getline解释后的代码示例)

std::getline将指定的分隔符视为行尾字符。通常使用它的方法是首先获取由EOL分隔的整行,然后使用分隔符从该行获取行,例如,'

下面是一些实现您想要的功能的代码

 std::map<std::string, int> nameCount;
 std::ifstream myfile(filename.c_str(),std::ios::in);
 std::string line;
 while(std::getline(myfile, line))
 {
    std::stringstream linestream(line);
    std::string       name;
    while (std::getline(linestream, name, ','))
    {
      if (nameCount.find(name) != nameCount.end())
      {
        nameCount[name]++; // increases the tally for name
      }
      else
      {
        nameCount[name] = 1; // inserts name into map and sets the tally to 1
      }
    }
 }
 // now output the map
 std::map<std::string, int>::iterator namecountitr;
 for (namecountitr = nameCount.begin(); 
       namecountitr != nameCount.end(); namecountitr++)
 {
      std::cout << namecountitr->first.c_str() << ":" 
      << namecountitr->second << std::endl;
 }
std::映射名称计数;
std::ifstream myfile(filename.c_str(),std::ios::in);
std::字符串行;
while(std::getline(myfile,line))
{
std::stringstream linestream(行);
std::字符串名;
while(std::getline(linestream,name,,'))
{
if(nameCount.find(name)!=nameCount.end())
{
nameCount[name]++;//增加name的计数
}
其他的
{
nameCount[name]=1;//将名称插入映射并将计数设置为1
}
}
}
//现在输出地图
std::map::迭代器namecountitr;
for(namecountitr=nameCount.begin();
namecountitr!=nameCount.end();namecountitr++)
{

std::cout first.c_str()我可以手动将名字添加到向量中,然后在循环中将迭代器向前推进1吗?另外,nameStrage.end()是否提供指向向量最后一个元素(可访问)的指针,或者在不可访问的地方通过它?在STL容器中,
end()是
方法返回一个超过容器中最后一个元素末尾一个位置的值。因此
end()
不会返回指向有效对象的迭代器,而是指示何时超过容器的末尾。这就是为什么通常会看到类似于(iter=container.begin()的
的代码;iter!=container.end();iter++)
…这是因为我们正在测试增量何时超过容器的末尾。当我们达到该点时,我们退出循环,而不取消引用该“end”
for ( it = X.begin(); it != X.end(); it++ )
for ( it = nameStorage.begin(); it <= nameStorage.end(); it++ )
for ( it = nameStorage.begin(); it != nameStorage.end(); it++ )
else if ( it == nameStorage.end() ) {
if (std::find(nameStorage.begin(), nameStorage.end(), tempInput) != nameStorage.end())
{
 /// temp struct blah blah blah
 nameStorage.push_back(tempStruct);
}
if ( tempInput == it->inputName ) {
if (!tempInput.compare(it->InputName))
std::map<std::string, int> nameStorage;

if (nameStorage.find(tempInput) != nameStorage.end())
{
 nameStorage[tempInput]++;
} else
{
 nameStorage[tempInput] =1;
}
std::map<std::string, int> nameCount;
 std::map<std::string, int> nameCount;
 std::ifstream myfile(filename.c_str(),std::ios::in);
 std::string line;
 while(std::getline(myfile, line))
 {
    std::stringstream linestream(line);
    std::string       name;
    while (std::getline(linestream, name, ','))
    {
      if (nameCount.find(name) != nameCount.end())
      {
        nameCount[name]++; // increases the tally for name
      }
      else
      {
        nameCount[name] = 1; // inserts name into map and sets the tally to 1
      }
    }
 }
 // now output the map
 std::map<std::string, int>::iterator namecountitr;
 for (namecountitr = nameCount.begin(); 
       namecountitr != nameCount.end(); namecountitr++)
 {
      std::cout << namecountitr->first.c_str() << ":" 
      << namecountitr->second << std::endl;
 }