• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1338
  • Last Modified:

Error: string iterator is not incrementable

Hello Everyone,

I am working on a program that is reading lines from a file and then count the total amount of words that are in the file.  When the program goes into this function

string lowerCase(string& strToConvert)
{
      string newString = strToConvert;
      for(string::iterator i=newString.begin();i!=newString.end();  ++i)
      {
        unsigned char c = *i;
         
         if(isalpha(c))
             *i = tolower(c);

         else if(ispunct(c) || isalnum(c))
         {
               i = newString.erase(i);
               
         }

         else if((int)c > 127)
         {
               i = newString.erase(i);

         }
        
   }
      return newString;
}

It is receiving this error
 Error
Also, the program must remove char that are numbers and punctuations.  But if there are multiple numbers or punctuations back to back the iterator is skipping over the following char.  
#include <iostream>
#include <string>
#include<cctype>
#include<fstream>
#include<cstdlib>
#include<algorithm>
#include<sstream>
#include<vector>
using namespace std;
 
string lowerCase(string&);
int determine_File_Size(int&);
 
int main()
{
    string strToConvert;  //The string that will be converted.
 	

  cout<<"***********************************"<<endl;
  cout<<"	Converter Program	"<<endl;
  cout<<"***********************************"<<endl;
 

 ifstream stringFile("sample.txt");

  int count = 0; 

  string word;

  vector<string> converted_line;

  string new_line;
  
  stringFile.unsetf(ios::skipws);

  while( getline(stringFile, word,'\n'))
  {
		new_line = lowerCase(word);
		
		converted_line.push_back(new_line);

		 istringstream is(new_line);

	  while(getline(is, new_line, ' '))
			count++;

  }


 
  determine_File_Size(count);

  cout<<"Word Count "<<count<<endl;

	stringFile.close();

  system("PAUSE");
    return 0;
}

 
string lowerCase(string& strToConvert)
{
	string newString = strToConvert;
	for(string::iterator i=newString.begin();i!=newString.end();  ++i)
	{
	  unsigned char c = *i;
   	
	   if(isalpha(c))
		 *i = tolower(c);

	   else if(ispunct(c) || isalnum(c))
	   {
		   i = newString.erase(i);
		   
	   }

	   else if((int)c > 127)
	   {
		   i = newString.erase(i);

	   }
	  
   }
	return newString;
}

int determine_File_Size(int& count)
{

	int returnSize = 0;

	if(count >= 50000)
	  {
		  cout<<"The File Size Will Be 50000"<<endl;
		  returnSize = 50000;
	  }

	 else if(count >= 10000)
	  {
		  cout<<"The File Size Will Be 10000"<<endl;
		  returnSize=10000;
	  }

	 else if(count >= 1000)
	  {
		  cout<<"The File Size Will Be 1000"<<endl;
		  returnSize=1000;
	  }

	else if(count >= 100)
	  {
		  cout<<"The File Size Will Be 100"<<endl;
		  returnSize=100;
	  }

	else
	{
		cout<<"The File Size Will Be "<<count<<endl;
		returnSize=count;
	}

		return returnSize;

}

Open in new window

0
brich744
Asked:
brich744
  • 3
  • 2
  • 2
2 Solutions
 
brich744Author Commented:
Here is the file that I am testing out sample.txt
0
 
jkrCommented:
The problem is that - unless you use 'std::list' - all iterators get invalidated by an 'erase()' operation, so your code is not safe. Better make that
string lowerCase(string& strToConvert)
{
      string newString; // start with an empty string
      for(string::iterator i=strToConvert.begin();i!=strToConvert.end();  ++i)
      {
        unsigned char c = *i;
         
         if(isalpha(c))
             newString.push_back(tolower(c));

         else if(ispunct(c) || isalnum(c))
         {
               continue;
               
         }

         else if((int)c > 127)
         {
               continue;

         }
        
   }
      return newString;
}

Open in new window

0
 
jkrCommented:
Oh, BTW, it would be a good idea to make the input parameter a 'const string&'
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
phoffricCommented:
In lowerCase, you need to save the space so that you can parse the line in Line 44.

I suppose using iterators is considered more elegant (and you learned something from this error). But your original solution of using indexes seemed adequate.

Also, I see you have thrown away the special chars. If you are parsing web sites of languages that need these special chars, then you may run into trouble. What are your requirements?
/* add to lowerCase */
         else if( c == ' ') 
             newString.push_back(c);

/* Line 44: */
               while(getline(is, new_line, ' '))  
                        count++;

Open in new window

0
 
phoffricCommented:
Recall that
      while(getline(is, new_line, ' '))
will sometimes yield a zero length string (e.g., two or more spaces in a row; or a leading space), so don't increment count when that happens.
0
 
brich744Author Commented:
My requirements is that my professor will be pulling essays from a website. But here is the actual assignment:

Hash Tables:

(If your program does not compile, you will lose all the points.)

In this homework, you will run experiments to determine which hash code is suitable for strings – polynomial hash code or cyclic shift hash code?  In addition to your textbook, you can read about these two types of hash code in the provided handout and at  http://www.csl.mtu.edu/cs2321/www/newLectures/16_Hash_Table.html

You will perform a comparative analysis that studies the collision rates for the following hash codes for character strings:

a)      Polynomial hash code with parameter a = 1
b)      Polynomial hash code with parameter a = 8
c)      Polynomial hash code with parameter a = 16
d)      Polynomial hash code with parameter a = 31
e)      Polynomial hash code with parameter a = 33
f)      Cyclic shift hash code for a shift amount of 0
g)      Cyclic shift hash code for a shift amount of 5
h)      Cyclic shift hash code for a shift amount of 10

Use a hash table to determine collisions, but only count collisions where different strings map to the same hash code (not if they map to the same location in this hash table because different hash codes can map to the same location). Note that identical words will have the same hash code and make sure that you do not count that towards a collision. Test these hash codes on text files found on the internet. For input text files, you can cut and paste essays from the following website http://www.npr.org/templates/story/story.php?storyId=4538138 or use any input text files of your choice. For simplicity, restrict your text files to contain only lower-case letters and spaces. You should use text files that contain exactly 100 words, 1000 words, 10,000 and 50,000 words. For this purpose, you must write a separate simple C++ program to sanitize your input files such that they contain only lower-case letters and spaces as well as to ensure that their length is one of 100 words, 1000 words, 10,000 and 50,000 words. If you cannot find a file big enough to contain 50,000 words, just concatenate different files to create a single larger file.

You can either use the Hash Table implementation from the course textbook website, modify that or custom design your own hash table from scratch for this particular task – it need not necessarily be implemented using classes. (If I were you, I would custom design my own hash table for this task.) Your output should be to a file in a neat 3-column table format where the first column will list the type of hash code (items (a)-(h) above), the second column will list the name of the input file (indicating whether it contains 100, 1000, 10000 or 50000 words) and the third column will list the number of collisions.
0
 
phoffricCommented:
>> or use any input text files of your choice.
Looks like you can limit your input files to include only ASCII chars.
The sanitized file is suppose to contain spaces. From the assignment, it is probably ok to collapse multiple spaces to a single space, but you can answer that better.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

  • 3
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now