Barney Chambers
Barney Chambers

Reputation: 2783

Indexing a Vector C++

I am new to Vectors, I think I have a syntactical error, or maybe I'm not calling .at() properly

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <ctype.h>
#include <vector>

using namespace std;

std::vector<string> symbols;
std::vector<int> symbolPos;

void addSymbol(string entry, int position){
    for (std::vector<string>::const_iterator i = symbols.begin(); i != symbols.end(); ++i){
        cout << "*i is: " << *i << endl;
// vvvvvvvvvvvvvvvvvvvvv Problematic line here vvvvvvvvvvvvvvvvvvvvv        
    if (symbols.at(i)==entry){
// ^^^^^^^^^^^^^^^^^^^^^ Problematic line here ^^^^^^^^^^^^^^^^^^^^^
            cout << "same entry" << endl;
            break;
        }

        else{
            symbols.push_back(entry);
            symbolPos.push_back(position);
        }
    }
}

My compiler is throwing an error, saying that .at() cannot be found. What am I doing wrong here?

assembler.cpp: In function ‘void addSymbol(std::string, int)’:
assembler.cpp:31: error: no matching function for call to ‘std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::at(__gnu_cxx::__normal_iterator<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)’
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_vector.h:650: note: candidates are: typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::reference std::vector<_Tp, _Alloc>::at(size_t) [with _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Alloc = std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_vector.h:668: note:                 typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_reference std::vector<_Tp, _Alloc>::at(size_t) const [with _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Alloc = std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]

Upvotes: 1

Views: 3194

Answers (6)

user4915609
user4915609

Reputation:

There is no method "at" in vector which expects iterator as an input . It expects size_type parameter . Since you are using an iterator you can simply do strcmp(*i,entry) . Or another way is to simply switch from using iterator to using operator[] of vector i.e

    for(int i=0;i<v.size();i++){
   cout<<i<<" th element : "<<v[i]<<endl;
   if(v[i]==entry){
    cout<<"Entry Already Exists"<<endl;
    break;
   }
 }

Another very easy way is to use "find" method , by which you can simply search for existence of entry in the present list

Upvotes: 0

Praetorian
Praetorian

Reputation: 109089

vector::at expects an argument of type vector::size_type, which is typically an alias for size_t; this is exactly what the error messages are telling you. You're trying to pass an instance of vector::iterator instead.

In your example you already have an iterator to the vector element, simply dereference it and do the equality comparison.

if (*i==entry)

You have bigger problems than that though, your entire for loop is basically undefined behavior waiting to happen. Say you pass an entry to addSymbol that doesn't match the first element in symbols. Your code causes the entry to be push_back'd into symbols, which will cause i to be invalidated if the vector need to reallocate storage. The for loop then increments i, which is undefined behavior. Moreover, do you want to keep iterating over the vector once you've added the element to the vector?

I think what you want to do is check whether the vector contains any element that matches entry, and add it if it doesn't exist. To do this, use find.

if(std::find(symbols.begin(), symbols.end(), entry) == symbols.end()) {
  // entry doesn't exist in the vector
  symbols.push_back(entry);
  symbolPos.push_back(position);
}

Upvotes: 5

911
911

Reputation: 928

Using iterators

void addSymbol(string entry, int position){

// you can use find function instead of using your own loop
std::vector<string>::iterator i = find(symbols.begin(), symbols.end(), entry);

// if not found
if (i == symbols.end()){
symbols.push_back(entry);
symbolPos.push_back(position);
}
else
cout << "same entry" << endl;

}

Upvotes: 0

Pradheep
Pradheep

Reputation: 3819

You are trying to pass an interator to the symbols vector

   if (symbols.at(i)==entry)

iterators are not like looping integer variables. so the code must be

   if (*i == entry)

if you want to use at then replace the for loop with integer value like

   for (i = 0; i < symbols.size; ++i)

Upvotes: 0

Ali Kazmi
Ali Kazmi

Reputation: 1458

change this to

if (symbols.at(i)==entry)

to

if (symbols.at(*i)==entry)

Since this function is expecting an integer not a pointer. :)

Upvotes: 0

marom
marom

Reputation: 5230

You do not need to call at with i, since i is an iterator, so a pointer.like object and you can acces the corresponding value via *i. You can use at with a integer index.

Upvotes: 0

Related Questions