【问题标题】:Counting characters, a Java program and wc yield inconsistent results计数字符、Java 程序和 wc 产生不一致的结果
【发布时间】:2020-08-17 06:55:29
【问题描述】:

我编写了一个计算文件中字符数的 java 程序。为了检查程序是否正常工作,我在命令行 (linux) 中输入以下内容来检查字符数:

wc -m fileName

wc 的手册页中,我知道换行符包含在计数中。

这是我的java程序:

import java.io.IOException;
import java.io.File;
import java.util.Scanner;

public class NumOfChars {
  /** The main method. */
  public static void main(String[] args) throws IOException {
    // Check that command is entered correctly
    if (args.length != 1) {
      System.out.println("Usage: java NumOfChars fileName");
    }

    // Check that source file exists
    File file = new File(args[0]);
    if (!file.exists()) {
      System.out.printf("File %s does not exist\n", file);
    }

    // Create Scanner object
    Scanner input = new Scanner(file);

    int characters = 0;
    while (input.hasNext()) {
      
      String line = input.nextLine();

      // The number of characters is the length of the line plus the newline character
      characters += line.length() + 1;
    }
    input.close();

    // Print results
    System.out.printf("File %s has\n", args[0]);
    System.out.printf("%d characters\n", characters);
  }
}

我遇到的问题是,有时使用 java 程序报告的字符数与使用 wc 命令时得到的字符数不同。

这里有两个例子:

一个有效的。文件text.txt的内容是

This is some text
This is some text
This is some text
This is some text
This is some text
This is some text
This is some text
This is some text

wc -m text.txt 命令告诉我这个文件有 144 个字符。这很好,因为当我执行 java 程序 java NumOfChars text.txt 时,我还被告知该文件有 144 个字符。

一个不起作用的。文件Exercise06.java的内容是

import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/** Converts a hexadecimal to a decimal. */
public class Exercise06 {
  /** Main method */
  public static void main(String[] args) {
    // Create a Scanner
    Scanner input = new Scanner(System.in);

    // Prompt the user to enter a string
    System.out.print("Enter a hex number: ");
    String hex = input.nextLine();
    
    // Display result
    System.out.println("The decimal value for hex number "
      + hex + " is " + hexToDecimal(hex.toUpperCase()));
  }
  

  /** Converts hexadecimal to decimal.
      @param hex The hexadecimal
      @return The deciaml value of hex
      @throws NumberFormatException if hex is not a hexadecimal
    */
  public static int hexToDecimal(String hex) throws NumberFormatException {
    // Check if hex is a hexadecimal. Throw Exception if not.
    boolean patternMatch = Pattern.matches("[0-9A-F]+", hex);
    if (!patternMatch) 
      throw new NumberFormatException();

    // Convert hex to a decimal
    int decimalValue = 0;
    for (int i = 0; i < hex.length(); i++) {
      char hexChar = hex.charAt(i);
      decimalValue = decimalValue * 16 + hexCharToDecimal(hexChar);
    }
    // Return the decimal
    return decimalValue;
  }
  
  
  /** Converts a hexadecimal Char to a deciaml.
      @param ch The hexadecimal Char
      @return The decimal value of ch
    */
  public static int hexCharToDecimal(char ch) {
    if (ch >= 'A' && ch <= 'F')
      return 10 + ch - 'A';
    else // ch is '0', '1', ..., or '9'
      return ch - '0';
  }
}

wc -m Exercise06.java 命令告诉我这个文件有 1650 个字符。但是,当我执行 java 程序 java NumOfChars Exercise06.java 时,我被告知该文件有 1596 个字符。

我似乎无法弄清楚我做错了什么。谁能给我一些反馈?

**编辑:这是我在输入 head -5 Exercise06.java | od -c 时得到的结果

【问题讨论】:

  • 第二个文件(根据您发布的内容)有 54 行; wc/java 计数的差异为 54;正如 Federico 所暗示的那样……第二个文件是否来自 Windows,如果是,您确定不需要计算 2 个 EOL 字符 (\n\r) 吗? head -5 Exercise06.java | od -c 显示为 EOL 字符是什么?
  • @Mr.Young 我在暗示 Windows 使用两个字符来换行(正如 markp-fuso 所说)。您应该考虑将文件视为一堆字符而不是一堆行。
  • 关于您的编辑,您可以看到每行有两个换行符(准确地说是回车符 (\r) 和换行符 (\n))
  • @Mr.Young 您可以测试文件是否包含 CR+LF,在这种情况下计算结束行字符两次(就像 wc 一样)。
  • @FedericoklezCulloca 我明白了。我不明白我在看什么。我以前从未使用过该命令。所以你和markp-fuso是说如果文件是在Windows机器上写的,会发生这种情况吗?我想这可以解释为什么我只遇到少量文件的问题。我正在做一些课本上的练习。对于一些练习,我从本书的配套网站借用了代码。该代码的作者必须使用 Windows。谢谢!

标签: java linux gnu-coreutils


【解决方案1】:

有几种可能的解释:

  • 每行可能以多个字符结尾,例如在 Windows 上,每行以 CR + LF 结尾,而您的程序总是精确计算 1 个行结束字符。

  • wc 可能会采用与您的程序不同的字符编码,这可能导致多字节字符的字符计数不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-06
    • 2018-05-05
    • 2012-01-16
    • 1970-01-01
    • 2021-11-01
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多