Heh, well my daily project is near finished, and I was looking around for a way to get rid of punctuation from a character array. I looked through the web a bit, and only found immensely complicated formulas which I did not feel like dealing with.
So my question is: is there a simple way to get rid of punctuation using character arrays?

Also, in case you are interested, my project that I have been working on today is a 'bot' where you ask it questions, and it gradually builds up a data-base. Sort of like a small wikipedia. Here is the source code, if you feel like playing around with it:

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
	char user[255];
	do{
	cout << "Talk: ";
	cin.getline (user,255);
	for(int x=0;x<strlen(user);x++)
	{
		if ( user[x] >= 'A' && user[x] <= 'Z' )
			user[x] = static_cast<char> ( user[x] + 'a' - 'A' );
	}
	char question[255][255], answer[255][255], userans[255];
	int ans=0, x=0;
	ifstream fromfile("questions.txt");
	for(x=1;x<50;x++)
	{
		fromfile.getline(question[x], 255);
		if(strcmp (question[x], user) == 0)
			ans = x;
	}
	fromfile.close();
	ifstream tofile("answers.txt");
	for(x=1;x<50;x++)
		tofile.getline(answer[x], 255);
	tofile.close();
	if(ans==0)
	{
		cout << "I am sorry, but I do not know. What would your answer be?: ";
		cin.getline(userans,255);
		ofstream intofile("answers.txt",ios::app);
		intofile << endl << userans;
		intofile.close();
		ofstream tofile("questions.txt",ios::app);
		tofile << endl << user;
		tofile.close();
	}
	else
		cout << "Botman says: " << answer[ans] << endl;
	}while(strcmp ("let me leave", user)!= 0);
}

Recommended Answers

All 16 Replies

Check out the functions in ctype.h (include it as <cctype>). It has an ispunct() function which you could use as you're moving through your array. See this for a reference to all the functions in that header.

Check out the functions in ctype.h (include it as <cctype>). It has an ispunct() function which you could use as you're moving through your array. See this for a reference to all the functions in that header.

Thanks! That helped a lot, and I looked through it. I want it to get rid of the punctuation completely though, and not leave a 'space' in it's place.
I modified it this far:

#include <stdio.h>
#include <iostream>
#include <ctype.h>
using namespace std;
int main ()
{
  int i=0;
  int cx=0;
  char str[]="Hello, welcome! ";
  while (str[i])
  {
    if (ispunct(str[i])) 
	{
	str[i]=' ';
	}
    i++;
  }
  cout << str;
  return 0;
}

so it gets rid of the punctuation, but a space takes it's place. I also tested out the \b(backspace) function, but that deleted one character too many. Any help is appreciated.

So now create a new char array and copy all the non-spaces over (you could do the copying in combination with the first step if you copy all the non-punctuation over at that point). You know the new array will be less than or equal to the old one in size.

Easy way:
Copy the string a character at a time into another string in a loop. Don't copy the punctuation.

Harder way:
Set up two indices, one (indOrig) for pointing at the original string, one (indNew) for pointing at the new character position. Both start at 0.

During your loop,
1) copy the character from the indOrig position to the indNew position.
2) increment indNew for every non-punctuation character.
3) increment indOrig for every character.
Be sure you loop far enough to copy the trailing \0

Hmm, I tried 'what I think' is what you guys are saying, and it is still not working. Take a look:

#include <stdio.h>
#include <iostream>
#include <ctype.h>
using namespace std;
int main ()
{
  int i=0;
  int cx=0;
  char str[]="Hello, welcome!", newstr[]="---------------";
  while (str[i])
  {
    if (ispunct(str[i])==0) 
	{
	newstr[i]=str[i];
	}
    i++;
  }
  cout << newstr;
  return 0;
}

Who's/which idea did you use? It doesn't look like any of our suggestions.

If it was jonsca's, your arrays are equal in size and he distinctly said

You know the new array will be less than or equal to the old one in size.

You need different index values because you are removing characters so the indices will not be identical once punctuation is found.

Who's/which idea did you use? It doesn't look like any of our suggestions.

If it was jonsca's, your arrays are equal in size and he distinctly said

You need different index values because you are removing characters so the indices will not be identical once punctuation is found.

haha, I am either incredibly stupid, or yea..that's probably it, cause I don't get it.

Could you guys give me an example? This is not homework--just something I am doing on my free time.

If newstr and str share the same i index, lets say position 3 of str was a period. What happens with index 3 of newstr? It'll be a gap you'll be (almost) back to your original problem.

From Mr. P (my emphasis added):

2) increment indNew for every non-punctuation character.
3) increment indOrig for every character.

You need a separate index for the newstr array.

Please decipher this statement as it pertains to coding:

You need different index values because you are removing characters so the indices will not be identical once punctuation is found.

What is an index value?
What are indices?
Pertaining to the program you wrote, how did you 'remove punctuation'?
Anything else you can explain?

I'm asking because in programming you must figure this stuff out. These are very simple (you will agree in another week, believe me) ideas.

Try doing this on paper. Write down your sentence. Copy each valid character one at a time and keep track of the character position in each sentence. When you understand the technique on paper, how do you tell the computer to do exactly what you just did? After all, you are a computer too.

Honestly I don't know, I really do not. I am so lost, that I feel like abandoning the project.
"Index Value: In computer science, an index can be: # an integer which identifies an array element # a data structure that enables sublinear-time lookup"
indices: essentially another version of 'index'.
I wrote a sentence on the piece of paper, and 'subtracted' the punctuation, which decreased the sentence size by two. I know what I 'have' to do, I just don't know how to implement it.

How am I supposed to reduce the size, I do not know. I did however modify my program in a different way which does exactly what I want it to do....except it beeps. -.-

#include <stdio.h>
#include <iostream>
#include <ctype.h>
using namespace std;
int main ()
{
  int i=0;
  int cx=0;
  char str[]="Hello, welcome!", newstr[]="---------------";
  while (str[i])
  {
    if (ispunct(str[i])!=0) 
		str[i]='\a';
    i++;
  }
  cout << str;
  return 0;
}

I would really just like an example at this point, so I can analyze it to see what it was I needed to do. I do not just take examples and paste them into my code, I make sure I know how they work before I do so..a common mistake made by most programmers. Sadly I have searched the web quite a lot, and could not find any examples using this method, and I am doubting if there is one. However, each time I review what you guys have said, I realize there is another method..I just don't know how to use it yet. I have only 1 semester of 'high school' programming experience, so I am really kind of a newbie. =/

If newstr and str share the same i index, lets say position 3 of str was a period. What happens with index 3 of newstr? It'll be a gap you'll be (almost) back to your original problem.

<snip>


You need a separate index for the newstr array.

Declare an integer j (or call it counter2 or any number of things). You need to increment j every time you get a "good"(non-punctuation) character so that you know what the next slot in newstr is. Once you've hit some spaces j wouldn't be equal to i but in your code you assume they'll match up. If I'm photocopying a bunch of sheets and passing them to you to file but I'm skipping the blank sheets, how will you know in which slot to place them. I pass you sheets 0-3, skip over 4, and now I pass you sheet 5. What slot is it going into? not 5, but 4 on your side. You would keep your own count separate.

You're so close I wouldn't give up at this point.

Declare an integer j (or call it counter2 or any number of things). You need to increment j every time you get a "good"(non-punctuation) character so that you know what the next slot in newstr is. Once you've hit some spaces j wouldn't be equal to i but in your code you assume they'll match up. If I'm photocopying a bunch of sheets and passing them to you to file but I'm skipping the blank sheets, how will you know in which slot to place them. I pass you sheets 0-3, skip over 4, and now I pass you sheet 5. What slot is it going into? not 5, but 4 on your side. You would keep your own count separate.

You're so close I wouldn't give up at this point.

Okay, so once I calculate how many characters are in the string, what do I do from that point? It is easier for me to understand this if I have examples. I am no English guru, never been very good with word problems.

int j;//my addition
while (str[i])
  {
    if (ispunct(str[i])==0) 
	{
	newstr[i]=str[i];
	}
    i++; //this is keeping track of str
  }

When in here do we know, ok we've got a non-punctuation character and can increment the j counter? Where can we be sure of that? So j is the counter for newstr which we would increment when we were sure of having a non-punctuation character to copy in.
Again, say we have 0 thru 6, we want to copy this into another array and we keep track of that number of items copied over:
[i|j|k] so we have 0 thru 2, and we skip the period so then we have [i|j|k|m|n|o] and we knew to put m in at position 3 solely because we kept track of it.

int j;//my addition
while (str[i])
  {
    if (ispunct(str[i])==0) 
	{
	newstr[i]=str[i];
	}
    i++; //this is keeping track of str
  }

When in here do we know, ok we've got a non-punctuation character and can increment the j counter? Where can we be sure of that? So j is the counter for newstr which we would increment when we were sure of having a non-punctuation character to copy in.
Again, say we have 0 thru 6, we want to copy this into another array and we keep track of that number of items copied over:
[i|j|k] so we have 0 thru 2, and we skip the period so then we have [i|j|k|m|n|o] and we knew to put m in at position 3 solely because we kept track of it.

Hmm, yes this is essentially what I had on the previous page, which kept giving me a '-' where the punctuation should be. This is still doing that. The only difference is the introduction to j, and I am very confused as to what I should do with j at this point.

Here is my code:

#include <stdio.h>
#include <iostream>
#include <ctype.h>
using namespace std;
int main ()
{
	int i=0;
	int cx=0;
	char str[]="Hello, welcome!", newstr[]="---------------";
	int j=0;
	while (str[i])
	{
		if (ispunct(str[i])==0) 
		{
			newstr[i]=str[i];
			j++;
		}
		i++; 
	}
  cout << newstr;
  return 0;
}

That was your code that I had pasted in. I was just trying to narrow down the window for you to find the spot for it. You've got j in the right spot now. Use it to index your newstr array, so newstr[j] instead of i. Trace a sample run through by hand (or with your debugger) and see what the results are.

commented: Thanks a bunch! +1

That was your code that I had pasted in. I was just trying to narrow down the window for you to find the spot for it. You've got j in the right spot now. Use it to index your newstr array, so newstr[j] instead of i. Trace a sample run through by hand (or with your debugger) and see what the results are.

Thanks a bunch! I finally got it. :P I feel like a retard, but it's an accomplishment.

Now to get rid of spaces...

#include<iostream>
#include<fstream>
#include<ctype.h>
using namespace std;
int main()
{
	char user[255]="";
	do{
	int j=0,l=0;
	char newuser[255]="";
	cout << "Talk: ";
	cin.getline (user,255);
	for(int x=0;x<strlen(user);x++)
	{
		if ( user[x] >= 'A' && user[x] <= 'Z' )
			user[x] = static_cast<char> ( user[x] + 'a' - 'A' );
		if (ispunct(user[x])==0) 
		{
			newuser[j]=user[x];
			j++;
		}

	}
	for(int x=0;x<255;x++)
		user[x]=newuser[x];
	char question[255][255], answer[255][255], userans[255];
	int ans=0, x=0;
	ifstream fromfile("questions.txt");
	for(x=1;x<250;x++)
	{
		fromfile.getline(question[x], 255);
		if(strcmp (question[x], user) == 0)
			ans = x;
	}
	fromfile.close();
	ifstream tofile("answers.txt");
	for(x=1;x<250;x++)
		tofile.getline(answer[x], 255);
	tofile.close();
	if(ans==0)
	{
		cout << "I am sorry, but I do not know. What would your answer be?: ";
		cin.getline(userans,255);
		ofstream intofile("answers.txt",ios::app);
		intofile << endl << userans;
		intofile.close();
		ofstream tofile("questions.txt",ios::app);
		tofile << endl << user;
		tofile.close();
	}
	else
		cout << "Botman says: " << answer[ans] << endl;
	}while(strcmp ("let me leave", user)!= 0);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.