How to display data from txt file in specific form

2019-08-18 14:37发布

问题:

I have a text file input which contains data as below. How can I display data from the text file into specific format?

Monday
Jessy
Walking
20 minutes
Matthew
Run
20 minutes
Karen
Jogging
40 minutes
Jessica
Run
12 minutes
Tuesday
Messia
Walking
10 minutes
Matthew
Run
20 minutes
Pete
Run
10 minutes
Carol
Walking
30 minutes

I want to display data from the text file into this format:

Day            Name               Type of exercise           Time
Monday         Jessy              Walking                    20 minutes
               Matthew            Run                        20 minutes
               Karen              Jogging                    40 minutes
               Jessica            Run                        12 minutes 
Tuesday        Messia             Walking                    10 minutes
               Matthew            Run                        20 minutes
               Pete               Run                        10 minutes
               Carol              Walking                    30 minutes

回答1:

I just threw this together quickly, but what about something like:

static final String[] DAYS =
{ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };

public class ActivityEvent
{
  public int day;
  public String name;
  public String typeOfExercise;
  public String time;
}

public List loadActivities(String filename) throws IOException
{
  List activities = new ArrayList();
  FileInputStream fis = new FileInputStream(filename);
  InputStreamReader isr = new InputStreamReader(fis);
  BufferedReader br = new BufferedReader(isr);
  int lastDay = -1;
  String line;
  while ((line = br.readLine()) != null)
  {
      line = line.trim();
      int day;
      for (day = DAYS.length - 1; day >= 0; day--)
      {
          if (line.equals(DAYS[day]))
          {
              break;
          }
      }
      String name;
      if (day < 0)
      {
          day = lastDay;
          if (lastDay < 0)
          {
              throw new IOException(filename + " must start with day of week");
          }
          name = line;
      }
      else
      {
          name = br.readLine();
          if (name == null)
          {
              throw new IOException(filename + " expected name, reached end of file");
          }
      }
      String type = br.readLine();
      if (type == null)
      {
          throw new IOException(filename + " expected type of exercise, reached end of file");
      }
      String time = br.readLine();
      if (time != null)
      {
          throw new IOException(filename + " expected time of exercise, reached end of file");
      }
      ActivityEvent activity = new ActivityEvent();
      activity.day = day;
      activity.name = name;
      activity.typeOfExercise = type;
      activity.time = time;
      activities.add(activity);
  }
  return activities;
}

public void printActivities(List activities)
{
    StringBuilder str = new StringBuilder("Day\tName\tType of Exercise\tTime\n");
    int numActivities = activities.size();
    int lastDay = -1;
    for (int index = 0; index < numActivities; index++)
    {
        ActivityEvent activity = (ActivityEvent)activities.get(index);
        if (activity.day != lastDay)
        {
            str.append(DAYS[activity.day]);
        }
        str.append('\t');
        str.append(activity.name);
        str.append('\t');
        str.append(activity.typeOfExercise);
        str.append('\t');
        str.append(activity.time);
        str.append('\n');
    }
    System.out.print(str.toString());
}

And then invoke everything for example:

List activities = loadActivities("somefile.txt");
// Do optional sorting, etc. here.
printActivities(activities);


回答2:

I would have a look at Java's sprintf() function and it's ability to left/right justify data with specified widths.



回答3:

Regarding parsing the input:

One issue you will have is that each "record" of data (each row, in the ouput) is not a fixed size. Some are 3-tuples of name,exercise,time, and others are 4-tuples of day,name,exercise,time

That said, assuming the format you've given is really all there is to it, the issue can be worked around.

After reading a line, you could check for a weekday, and if so assume that's the start of a 4-tuple, and read the next 3 lines. If it is not a weekday, then assume it is a 3-tuple, and only read the next 2 lines.

If there might be "gaps" in the name, type, or time columns in the output as well, and in different combinations, it gets trickier.

You really need your program to have special knowledge about what values are valid in what columns. Eg, that 'Jessica' is not a valid type of exercise, and 'Jogging' is not a valid name.

Regarding formatting the output

Brian's answer is relevant.

It depends on the language you use. Most languages have a printf-equivalent. The formatting codes of printf allow you to pad with space, etc.

If you are using Perl (might be well-suited to this task), you can use formats