Java - Reading from file and stopping at specific value

时间:2019-04-17 02:50:06

标签: java

The goal is to read from a given file that has strings and integers. The file has the names of fictitious students along with their test scores. Some students have three test scores, some four, and some none at all. The way the program is supposed to stop and process the test scores for the students is when it finds "-1." Once it finds "-1," it's supposed to stop the loop, and process that student's scores. What I can't figure out is how to have the program stop when it runs into "-1."

When I run it right now, all it does is capture the names of all the students, along with their first test score.

    //Declare Variables
    String name;
    String grade;
    String inFile;
    String outFile;
    PrintWriter outputFile;
    int score1 = 0;
    int score2 = 0;
    int score3 = 0;
    int score4 = 0;
    int score5 = 0;
    int score6 = 0;

    //Get input file name
    System.out.print("Enter the input filename: ");
    inFile = KB.nextLine();

    File studentsFile = new File(inFile);
    Scanner scanFile = new Scanner(studentsFile);

    //Capture Student Info
    while(scanFile.hasNext()){
        name = scanFile.nextLine();
        if (scanFile.hasNextInt()){
            score1 = scanFile.nextInt();
            System.out.println(name);
            System.out.println(score1);
        }

Sample Input File:

     Introduction to Programming 1
     John Sweet
     87 76 90 100 -1
     Ali Hassan
     -1
     Willy Nilly
     73 63 74 70 -1
     Juju Smith Jr.
     89 90 78 88 -1
     Karl Kavington III
     90 100 80 70 -1
     Lary Howard Holiday
     80 77 67 67 -1
     Leo Gordon
     56 88 780 77 -1
     Jessy Brown -1
     90 80 88 92 -1
     Mr. Perfect
     100 100 100 100 -1
     Mr. Missing It All
     0 0 0 0 0 0 -1

EDIT: The program is supposed to read through one student and their test scores, perform some calculations, write those to an output file, and then repeat itself with the next student. It's to repeat itself until the end of the file.

2 个答案:

答案 0 :(得分:0)

好吧,如果您想停止读取文件,则可以在while循环内进行尝试:

if(score == -1 ){ break; }

您可以在条件内定义得分。甚至,如果分数超过100怎么办?您可以在条件中定义例如if(score<0 || score>100)

答案 1 :(得分:0)

为了在文件数据行中找到 -1 ,您将需要分析该行以查看它是否实际存在于同一行中包含的其他数据值之中。

在您的情况下,由于数据文件中包含的分数数据行(可能)始终需要 -1 结束(需要处理),因此您可以利用String#endsWith()方法或String#split()方法。由于文本数据文件中的数据始终始终为String类型,因此使用String方法轮询数据似乎很自然。

是的,如果使用正确的Scanner方法,则可以将数据读取为数值数据类型,但我认为您现在应该保持简单,仅将所有内容检索为String,因为将所有内容检索为String,然后再使用适当的Scanner用于检查是否有另一条文件数据行(对于您的 while 循环条件)使用的方法是Scanner#hasNextLine()方法,而不是Scanner#hasNext()方法。 Scanner#hasNext()方法更适合于检索字符串标记(单词)而不是整个字符串行。考虑到这一点,以下 while 循环条件会更合适:

while (scanFile.hasNextLine()) {
    // .... your loop code ....
}
  

结合使用String#endsWith()方法和String#split()方法:

因为您要从每个文件数据行中查找特定条件,例如 学生姓名 学生分数 ,尤其是 学生分数 末尾的 -1 ,您可以安全地使用 String#endsWith() 方法来查看分数数据行中是否包含 -1 ,例如:

while (scanFile.hasNextLine()) {
    name = scanFile.nextLine();
    scroresString = scanFile.nextLine();
    if (scroresString.trim().endsWith("-1")) {
        // Do what needs to be done with the data on this line.
    }
}

一旦确定在分数数据行的末尾确实存在 -1 的事实,则可以删除该-1并将其余的分数数据使用< strong> String#split()方法。如果一切顺利,则该学生的所有分数都将包含在一个字符串数组中,您可以从中获取每个数组元素,将其转换为Integer或Double并进行所需的计算(无论它们可能是多少)。这样进行操作还可以打开检查分数数据错误的机会,因为在分数中可能 是输入错误,例如字母字符与数值。

以下是这种机制的整体示例(由您决定是否写入文件):

Scanner KB = new Scanner(System.in);

List<String> noScores = new ArrayList<>();               // Students with No Scores Avbailable
List<String> notReadyForProcessing = new ArrayList<>();  // Students with No -1 attached to end of scores.
List<String> dataError = new ArrayList<>();              // Students With Score Data Errors
String name = "";
String scoresString = "";

//Get input file name
File studentsFile = null;
String inFile = null;
while (studentsFile == null) {
    System.out.print("Enter the input file name (enter q to quit): ");
    inFile = KB.nextLine();
    if (inFile.equalsIgnoreCase("q")) {
        System.out.println("Bye-Bye");
        System.exit(0);     // End Application
    }
    studentsFile = new File(inFile);
    // Does the supplied file name exist?
    if (!studentsFile.exists() ) {
        // Nope!
        studentsFile = null;
        System.out.println("Can not locate the file specified (" + inFile 
                        + ")! Please try again." + System.lineSeparator());
    }
}
System.out.println();


// Using 'Try With Resouces' so as to auto-close the Scanner reader
try (Scanner scanFile = new Scanner(studentsFile)) {
    //Skip first line in file since it's a Header Line.
    scanFile.nextLine();
    while (scanFile.hasNextLine()) {
        // Read in the Student Name
        name = scanFile.nextLine().trim();
        // Skip blank lines...
        if (name.equals("")) {
            continue;
        }
        /* If a name contains a -1 at the end then it is 
           obviously flagged for some reason. (unless that
           was a typo in the file)  :p   */
        if (name.endsWith("-1")) {
            name = name.replace("-1", "| Name Flagged: -1 (see records file)");
        }

        // Read in the Student's Scores
        scoresString = scanFile.nextLine();
        // If there is just a -1 then the current student has no scores
        if (scoresString.equals("-1")) {
            // Add the Student to the 'No Scores' List
            noScores.add(name + " | " + scoresString);
        }
        // Otherwise, see if -1 is at end of the scores
        else if (scoresString.endsWith("-1")) {
            // YUP!
            /* Calculate Scores Average... 
                   This should realy be done in a method or Class.
                   There are MANY WAYS to simplify this code. The hope is that this will 
                   give you ideas for other possible situations in the future. 
                       ======================================================================  
             */

            // Get rid of the -1 at the end of scores String
            String procScores = scoresString.substring(0, scoresString.lastIndexOf("-1")).trim();
            // Place the Scores into a Integer Array. 
            // First, Split the scores into a String Array since it all starts as string
            String[] strgScoresArray = procScores.split("\\s+");
            // Then convert each array element into Integer data type
            // and sum them.
            double scoreTotal = 0.0d;
            double scoreAverage = 0.0d;
            int validScoreCount = 0;
            for (int i = 0; i < strgScoresArray.length; i++) {
                /* Make sure the String numerical value is indeed 
                       a string representation of a Integer or Double
                       numerical value.   */
                if (strgScoresArray[i].matches("-?\\d+(\\.\\d+)?")) {
                    scoreTotal += Double.parseDouble(strgScoresArray[i]);
                    validScoreCount++;
                }
                else {
                    // Falty data...Save the Student record into the dataError List.
                    dataError.add(name + " | " + scoresString + " | Element In Error: " + strgScoresArray[i]);
                }
            }
            // Calculate the average Score:
            scoreAverage = scoreTotal / validScoreCount;

            // Display the results to Console Window...
            System.out.println("Student Name:\t" + name);
            System.out.println("Student Scores:\t" + procScores);
            System.out.println("Average Score:\t" + scoreAverage
                    + " From '" + validScoreCount + "' Valid Score Results."
                    + System.lineSeparator());
        }
        // Otherwise, Place the current Student into the 
        // 'Not Ready For Processing' List
        else {
            notReadyForProcessing.add(name + " | " + scoresString);
        }
    }
}
catch (FileNotFoundException ex) {
    ex.printStackTrace();
}

System.out.println();
// Display the other Lists generated (if you like).
System.out.println("Students That Contain No Scores:" + System.lineSeparator()
                + "================================");
if (noScores.isEmpty()) {
    System.out.println("NONE");
}
else {
    for (int i = 0; i < noScores.size(); i++) {
        System.out.println(noScores.get(i));
    }
}

System.out.println();
System.out.println("Students Not Ready For The Averaging Process:" + System.lineSeparator()
        + "=============================================");
if (notReadyForProcessing.isEmpty()) {
    System.out.println("NONE");
}
else {
    for (int i = 0; i < notReadyForProcessing.size(); i++) {
        System.out.println(notReadyForProcessing.get(i));
    }
}

System.out.println();
System.out.println("Students Records With Score Data Errors:" + System.lineSeparator()
        + "========================================");
if (dataError.isEmpty()) {
    System.out.println("NONE");
}
else {
    for (int i = 0; i < dataError.size(); i++) {
        System.out.println(dataError.get(i));
    }
}