sam
sam

Reputation: 153

Extracting data from user input String into arrays

My last attempt at getting help was poorly explained on my part so I thought I'd try again and be clearer.

I am writing a program that is supposed to have a user enter the number of exams, homework, and quizzes in a class, and then the scores for each student on all of those assignments. Ex:

Please provide grade item details

Exams   (number, points, weight):3 100 60

Quizzes (number, points, weight):3 10 20

Homework (number, points, weight):3 10 20

What would you like to do?

1 Add student data

2 Display student grades & statistics

3 Plot grade distribution

4 Quit

Your choice: 1

Enter student data:

data>Bob Jones: e100 e80 e90 q10 q10 q0 h10 h5 h10

data>Joe Smith: e85 e90 e100 q10 q10 q5 h0 h10 h5

data>Sam Johnson: q10 h10 h0 h10 e60 e100 e90 q10 q8

My main issue is that I am struggling with how to separate one line of data into four different arrays: one for the name, one for exam scores, one for quiz scores, and one for homework scores.

What I have tried to do up to this point is shown here:

  if(input == 1){



        for(int i = 0; i <= students;){
            for (boolean done = false;done == true;){
                System.out.println("Enter student data: ");      
                System.out.print("data>");

                String[] readInput = s.next().split(":");

                String name = readInput[0];     

                String scoreString = readInput[1];

                String [] scores = scoreString.split("\\s+");

                char type = scores[0];
                String inputscore = scores.substring(1);
                int score = Integer.valueOf(inputscore);

                if (type == 'e'){

So what I'm attempting to do, is split the entered line of data into an array called readInput, with index 0 being the name and index 1 being the list of scores. I then create two strings, one called name and one called score, with the data from index 0 and 1. Then my idea was to read the character before each entered score ("e100" for example) to determine which array it should go into. I feel like I'm doing this in a way that doesn't make much sense and that there's probably a way easier way to do it, but I have kind of hit a wall here trying to figure it out.

My other concern is that when a user fails to enter all of the scores (like for example, there are 3 exams in the course but the user only enters two exam scores) the ones not entered go into the array as 0. But will that happen automatically or not?

Upvotes: 0

Views: 674

Answers (3)

Vihar
Vihar

Reputation: 3831

You can use this approach

    if (input == 1){

        String name = readInput[0];                 
        String scores = readInput[1];

        String s[]=scores.split("\\s+");


        examArray=0,harray=0;
        for(int i=0;i<s.length();i++){
           if(s.startsWith("e")) {
               string str=s.subString(1,s.length());
               exam[examArray++]=Integer.valueOf(str);
           }else
           {
             // same for different cases
           }
    }
}

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201439

First, I think you need a helper method to get the count(s) of a particular type of score. Something that takes in a String and returns the number of times a char appears. You can use String.toCharArray() and an enhanced for-each loop to get the count like,

private static int countChar(String in, char v) {
    int count = 0;
    if (in != null) {
        for (char ch : in.toCharArray()) {
            if (ch == v) {
                count++;
            }
        }
    }
    return count;
}

Then you might use a regular expression, for example \\D matches a single non-digit and \\d+ matches consecutive digits. So you could use that to create a Pattern and then iterate the array of grades like

String str = "Bob Jones: e100 e80 e90 q10 q10 q0 h10 h5 h10";
Pattern p = Pattern.compile("(\\D)(\\d+)");
String[] input = str.split("\\s*:\\s*"); // optional white space \\s*
System.out.println("Name: " + input[0]);
String[] grades = input[1].split("\\s+"); // one (or more) consecutive 
                                          // white space characters \\s+
int[] exams = new int[countChar(input[1], 'e')];
int[] quizs = new int[countChar(input[1], 'q')];
int[] homework = new int[countChar(input[1], 'h')];
int epos = 0, qpos = 0, hpos = 0;
for (String grade : grades) {
    Matcher m = p.matcher(grade);
    if (m.matches()) {
        String type = m.group(1);
        if (type.equals("e")) {
            exams[epos++] = Integer.parseInt(m.group(2));
        } else if (type.equals("q")) {
            quizs[qpos++] = Integer.parseInt(m.group(2));
        } else if (type.equals("h")) {
            homework[hpos++] = Integer.parseInt(m.group(2));
        }
    }
}
System.out.println("Homework: " + Arrays.toString(homework));
System.out.println("Quizs: " + Arrays.toString(quizs));
System.out.println("Exams: " + Arrays.toString(exams));

Output is

Name: Bob Jones
Homework: [10, 5, 10]
Quizs: [10, 10, 0]
Exams: [100, 80, 90]

Upvotes: 0

Foxsly
Foxsly

Reputation: 1028

You're on the right path; think about what you'd need to split on to get all the different exam scores. Everything seems to be separated by a space, so why not split again on that?

String[] scoreArray = scores.split(" ");
for(String score : scoreArray) {
    if(score.startsWith("e")) {
        //add to exam array
    } else if(score.startsWith("q")) {
        //add to quiz array
    } else if(score.startsWith("h")) {
        //add to homework array
    }
}

As far as your second question, these scores will not be entered in as 0 automatically. You will need to detect whether the given array is full (using the "number" value given as input to the "grade item details"). If it's not full, then fill it the rest of the way with 0s.

Upvotes: 1

Related Questions