10

Possible Duplicate:
JAVA: check a string if there is a special character in it

I am a novice programmer and am looking for help determining if a character is a special character. My program asks the user to input the name of a file, and the program reads the text in the file and determines how many blanks spaces, digits, letters, and special characters are in the text. I have the code completed to determine the blanks, digits, and letters, however am unsure of how to check if a character is a special character. Any help you can offer is appreciated and if something was not clear enough I can try to elaborate. My code so far is:

import java.util.Scanner;
import java.io.*;

public class TextFile{

public static void main(String[] args){

  Scanner input = new Scanner (System.in);
  String fileName;
  boolean goodName = false;
  int blankCount = 0;
  int letterCount = 0;
  int digitCount = 0;
  int specialcharCount = 0;
  String currentLine;
  char c;
  Scanner lineFile= null;
  FileReader infile;

  System.out.println("Please enter the name of the file: ");
  fileName = input.nextLine();

  while (!goodName) {
    try{
      infile = new FileReader(fileName);
      lineFile = new Scanner(infile);

      goodName= true;
    }
    catch(IOException e) {
      System.out.println("Invalid file name, please enter correct file name: ");
      fileName=input.nextLine();
    }
  }

  while (lineFile.hasNextLine()){
    currentLine = lineFile.nextLine();
    for(int j=0; j<currentLine.length();j++){
      c=currentLine.charAt(j);
      if(c== ' ') blankCount++;
      if(Character.isDigit(c)) digitCount++;
      if(Character.isLetter(c)) letterCount++;
      if() specialcharCount++;
    }
  }
}
}

I need something to put in the if statement at the end to increment specialcharCount.

Community
  • 1
  • 1
user1701604
  • 985
  • 4
  • 11
  • 15
  • 3
    What is your definition of "special character" by which you wish to count? – FThompson Oct 14 '12 at 19:40
  • 3
    Depending on your definition of special character a simple `else specialCharCount++` would do it. – Anthony Accioly Oct 14 '12 at 19:41
  • !@#$%^&*-_':.><,?/ and so on, pretty much anything thats not a letter digit or a space, thank you – user1701604 Oct 14 '12 at 19:41
  • Also take a look at: http://stackoverflow.com/questions/1795402/java-check-a-string-if-there-is-a-special-character-in-it – Anthony Accioly Oct 14 '12 at 19:42
  • I attempted the else statement however that includes all the numbers, blank spaces, and special characters. How would I do it so that it ONLY counts special characters? – user1701604 Oct 14 '12 at 19:51
  • @OP: replace `if(Character.isDigit(c))` and `if(Character.isLetter(c))` by `else if(Character.isDigit(c))` and `else if(Character.isLetter(c))` this way it will only enter the `else` statement if the character is not a space or a digit or a letter. – Anthony Accioly Oct 14 '12 at 19:57

4 Answers4

16

This method checks if a String contains a special character (based on your definition).

/**
 *  Returns true if s contains any character other than 
 *  letters, numbers, or spaces.  Returns false otherwise.
 */

public boolean containsSpecialCharacter(String s) {
    return (s == null) ? false : s.matches("[^A-Za-z0-9 ]");
}

You can use the same logic to count special characters in a string like this:

/**
 *  Counts the number of special characters in s.
 */

 public int getSpecialCharacterCount(String s) {
     if (s == null || s.trim().isEmpty()) {
         return 0;
     }
     int theCount = 0;
     for (int i = 0; i < s.length(); i++) {
         if (s.substring(i, 1).matches("[^A-Za-z0-9 ]")) {
             theCount++;
         }
     }
     return theCount;
 }

Another approach is to put all the special chars in a String and use String.contains:

/**
 *  Counts the number of special characters in s.
 */

 public int getSpecialCharacterCount(String s) {
     if (s == null || s.trim().isEmpty()) {
         return 0;
     }
     int theCount = 0;
     String specialChars = "/*!@#$%^&*()\"{}_[]|\\?/<>,.";
     for (int i = 0; i < s.length(); i++) {
         if (specialChars.contains(s.substring(i, 1))) {
             theCount++;
         }
     }
     return theCount;
 }

NOTE: You must escape the backslash and " character with a backslashes.


The above are examples of how to approach this problem in general.

For your exact problem as stated in the question, the answer by @LanguagesNamedAfterCoffee is the most efficient approach.

jahroy
  • 22,322
  • 9
  • 59
  • 108
  • 1+ for the `contains` solution. You have forgot to account for digits in your regex. – Anthony Accioly Oct 14 '12 at 20:22
  • Not a fan of the special characters string--think international character sets.....I very much prefer your first solution – Mizmor May 26 '16 at 19:32
  • I am somehow confused - the solution with regex is evaluating strings with only one digit. I mean s.matches("[^A-Za-z0-9 ]") will not work on a string like "a@b". Another version that I find more fit is to check if the String contains only legal characters (notice the * indicator, which matches more than one char): s.matches("[A-Za-z0-9 ]*"). Useful link: https://stackoverflow.com/questions/1795402/check-if-a-string-contains-a-special-character . – Victor Nov 06 '19 at 11:23
  • I think in your second approach, you should use (i+1) as endIndex instead of just 1. `s.substring(i, 1)` should be `s.substring(i, i+1)` – DesertPride Apr 20 '21 at 06:22
5

Take a look at class java.lang.Character static member methods (isDigit, isLetter, isLowerCase, ...)

Example:

String str = "Hello World 123 !!";
int specials = 0, digits = 0, letters = 0, spaces = 0;
for (int i = 0; i < str.length(); ++i) {
   char ch = str.charAt(i);
   if (!Character.isDigit(ch) && !Character.isLetter(ch) && !Character.isSpace(ch)) {
      ++specials;
   } else if (Character.isDigit(ch)) {
      ++digits;
   } else if (Character.isSpace(ch)) {
      ++spaces;
   } else {
      ++letters;
   }
}
  • If you refactor you if statements so that letters are the first ones to be matched and special characters are the last you can achieve the same results more efficiently by having only one call to each of the suggested `Character` methods. Plus it is good to keep in mind that [isSpace](http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isSpace(char)) has been deprecated in favor of [isWhitespace](http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isWhitespace(char)) and that those methods will also count characters such as `\t`, `\n`, `\r`, etc as spaces. – Anthony Accioly Oct 14 '12 at 20:10
2

You can use regular expressions.

String input = ...
if (input.matches("[^a-zA-Z0-9 ]"))

If your definition of a 'special character' is simply anything that doesn't apply to your other filters that you already have, then you can simply add an else. Also note that you have to use else if in this case:

if(c == ' ') {
    blankCount++;
} else if (Character.isDigit(c)) {
    digitCount++;
} else if (Character.isLetter(c)) {
    letterCount++;
} else { 
  specialcharCount++;
}
LanguagesNamedAfterCofee
  • 5,782
  • 7
  • 45
  • 72
1

What I would do:

char c;
int cint;
for(int n = 0; n < str.length(); n ++;)
{
    c = str.charAt(n);
    cint = (int)c;
    if(cint <48 || (cint > 57 && cint < 65) || (cint > 90 && cint < 97) || cint > 122)
    {
        specialCharacterCount++
    }
}

That is a simple way to do things, without having to import any special classes. Stick it in a method, or put it straight into the main code.

ASCII chart: http://www.gophoto.it/view.php?i=http://i.msdn.microsoft.com/dynimg/IC102418.gif#.UHsqxFEmG08

Azulflame
  • 1,534
  • 2
  • 15
  • 30