-1

I am trying to write a program that finds the longest line of text that the user provides. However, it does not work properly; it gives the last entered array with the first letter missing.

import java.io.*;
public class longestNoCopy{
    static final int MAXLINE = 100; 
    public static void main(String[] args) throws IOException{
        int len;
        int max;
        char line[] = new char[MAXLINE];
        char longest[] = new char[MAXLINE];
        max=0;
        while((len=getLine(line,MAXLINE))>0){
            System.out.printf("len: %d\n", len);
            if(len>max){
        //      System.out.println("New record");
                max=len;
                longest=line;
            }
        /*  System.out.print("\nLine: ");
            for(int i=0;line[i]!=0;i++)     
                System.out.print(line[i]);*/
            System.out.println("Longest line so far:");
            for(int i=0;longest[i]!=0;i++)      
                System.out.print(longest[i]);
        }
        if(max>0){
            System.out.printf("Longest line:\n");
            int i;
            for(i=0;i<longest.length;i++)
                System.out.print(longest[i]);
                System.out.printf("\ni: %d, Length: %d\n", i, max);
        }
    }
    static int getLine(char s[], int lim) throws IOException{
        InputStreamReader r = new InputStreamReader(System.in);
        int c = 0, i = 0;
        for(i=0;i<lim-1&&(c=r.read())!=-1&&c!='\n';++i){
            s[i]=(char)c;
        //  System.out.printf("s[%d]: %c\n", i, s[i]);
        }
        if(c=='\n'){
            s[i]=(char)c;
            ++i;
        }
        // System.out.printf("i: %d\n", i);
        s[i]='\0';
        return i;
    }
}

I commented out some print statements so you have the choice of activating them. If I enter:

Hi
my
name
is

It says: Longest line: s

Whereas the longest line should be: name By the way, I am running on the Ubuntu command line and use Ctrl+D to quit. I know a lot of the code is weird; I took some C code and tried to change it until it became a Java program to compare the two languages. Why is this error happening? To emphasize, I know this is not the usual way to do things in Java, I know about the Scanner class, etc. I am not using this code for a real application. I just want to know why this error occurs.

  • 2
    https://stackoverflow.com/questions/5287538/how-can-i-get-the-user-input-in-java – azro Aug 11 '19 at 19:23
  • 1
    Java has `String`, which turns this largely into a one liner of comparing your current stored "longest string"'s length against the input string. There's also many classes that make reading these streams easier, a typical Java beginner will run into the example of `Scanner` with System#in before anything in this example. Additionally, you don't have to null terminate strings in Java, an empty string is essentially an empty `char[]` array – Rogue Aug 11 '19 at 19:24
  • 4
    Yikes. It looks like C! As others have said, using Java idioms properly enables a solution with a few lines. – Gene Aug 11 '19 at 19:25
  • You might want to use what Java provides. Something like `BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String longest = in.lines().max(Comparator.comparing(String::length)) .orElseThrow(RuntimeException::new);` – Gene Aug 11 '19 at 19:44

1 Answers1

3

The main mistake you are making would be a bug in C as well:
You are treating reference assignment as buffer copy.

In Java, references are a bit like pointers in C.
There are differences, but they are not relevant to this example.

The problematic line is this:

longest=line;

Variable line holds a reference to an array of char. The line of code above copies the reference to this array in to variable longest.

It does not copy the array it self!

So, next time you read in to line, you overwrite the contents of the buffer.
Since longest and line refer (think point) to the same buffer in memory, your code prints out whatever was the last thing entered to that buffer.

If you want to preserve the longest word, you need to copy the actual characters one by one.
You can use a loop, or a Java utility class Arrays.copyOf or System.arraycopy.

The Arrays version will allocate the new array for you automatically.

Lev M.
  • 6,088
  • 1
  • 10
  • 23