简体   繁体   中英

parallel array for Visual Basic assignment

For this assignment I am being ask to "Read the file into parallel string arrays corresponding to the columns in the file". The columns in the file are: "P_CODE" "P_DESCRIPT" "P_INDATE" "P_QOH" "P_MIN" "P_PRICE". My question is "What is a parallel array?" and what does it look like. I took a guess at how I would imagine it might done but I'm not sure I'm on the right track.

  ========== project Inventory ========== 

Selecting the Read button shall cause the contents of the InventoryData.txt file to be read from your project's default folder. The file does contain a column header line.

Read the file into parallel string arrays corresponding to the columns in the file. After reading the file, close it. Display the contents of the file in the parallel arrays, including column titles, in the List box formatted using the Format() method. Left and right align columns according to convention for their type of data. Hint: Set the Font property of you List Box to a nonproportional space font such as Courier.

Write the contents of the file in the parallel arrays, including column titles, to a file named InventoryDataOut.txt created in your project's default folder. Delimit the columns with the pipe (|) symbol. Each inventory item to one line of output to the file.

This is what I have done so far. I just started so this is not functioning code.

 Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click

        Dim dirPath As String = "C:\Users\...\Inventory\"
        Dim filePath As String = dirPath & "InventoryData.txt"

        'Arrays
        Dim P_CODE As String()
        Dim P_DESCRIPT As String()
        Dim P_INDATE As String()
        Dim P_QOH As String()
        Dim P_MIN As String()
        Dim P_PRICE As String()


    ' Open file for reading

    Dim textIn As New StreamReader(
        New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))

    'Read in the lines of text into the String variables in the array;

    Dim i As Integer = 0
    Do While textIn.Peek <> -1
        Dim row As String = textIn.ReadLine
        Dim columns As String() = row.Split(CChar(" "))
        P_CODE(i) = columns(i)
        P_DESCRIPT(i) = columns(i)
        P_INDATE(i) = columns(i)
        P_QOH(i) = columns(i)
        P_MIN(i) = columns(i)
        P_PRICE(i) = columns(i)
        i = i + 1
    Loop


    '=====================================
    '- After reading the file, close it. 
    textIn.Close()

I get the following warning and error (for each array) :

Warning 1 Variable 'P_CODE' is used before it has been assigned a value. A null reference exception could result at runtime.

Columns as independant arrays ? :/


One line answer : You're doing it right !


However :

  • there are simplier ways to do this (in terms of usage and readability - not performance)
  • there are typos in your code.

StackOverflow's main purpose is not to teach basic language reference, but help you overcome a specific problem with the appropriate coding (while keeping in mind an answer can't be an answer if it doesn't provide the elements to answer OP's question)

The error you stated is not really related to the question "what is a parallel array". "Variable used before it has been assigned a value" . Of course ! Your array is Null . The variable is declared but no instance of it has been created. And Arrays are that strict in dotNet (unlike JavaScript)

What's your real question ?
It's more related to "how should I assign values to (parallel) array(s)" and could be reformulated like "How to read string values stored in a text file in parallel arrays and write them back ?"

Homework questions usually disallows the use of alternative approaches (and sometimes such homework questions are downvoted)

Different approaches like (using a database with linq or) :


Use File.ReadAllLines() to know the number of lines right from the beginning...

Declare your arrays top level : you won't be able to access them outside your btnRead Click otherwise.

Private P_CODE As String()
Private P_DESCRIPT As String()
' ...
Private P_PRICE As String()

Load the file content inside your btnRead Click...

Dim AllLines As String() = File.ReadAllLines(filePath)
' ^^ the above will open and close the file XD

Dim Columns As String()

' Initialize your arrays...
ReDim(P_CODE, AllLines.Length - 1)
ReDim(P_DESCRIPT, AllLines.Length - 1)
' ...
ReDim(P_PRICE, AllLines.Length - 1)

' set each cell value.
For LineIndex As Int32 = 0 To P_CODE.Length - 1
    Columns = AllLines(LineIndex).Split(" "c)
    P_CODE(LineIndex) = Columns(0)
    P_DESCRIPT(LineIndex) = Columns(1)
    ' ...
    P_PRICE(LineIndex) = Columns(5)

    ' Hey ! Your File Datas are ordered horizontaly,
    ' so Columns must be indexed from 0 to 5 
    ' instead of you "i" in your code in order 
    ' to correctly feed your parallel arrays
Next

Your teacher wanna force you to open the file using StreamReader and teach you to not forget to close the file... and use StreamReader.ReadLine() ... Okay..!

' ...

Dim LineIndex As Int32 = 0
Dim textIn As New StreamReader(filePath)
' ^^ why do you bother using a FileStream ?
Dim Row As String = textIn.ReadLine()
Dim Columns As String()

Do While row IsNot Nothing
    Redim Preserve P_CODE(LineIndex)
    Redim Preserve P_DESCRIPT(LineIndex)
    ' ...
    Redim Preserve P_PRICE(LineIndex)

    Columns = Row.Split(" "c)

    P_CODE(LineIndex) = Columns(0)
    P_DESCRIPT(LineIndex) = Columns(1)
    ' ...
    P_PRICE(LineIndex) = Columns(5)

    Row = textIn.ReadLine()
    LineIndex = LineIndex + 1
Loop

textIn.Close() ' Voila !

' /!\ Add at least a Try Catch enclosing your Do/Loop if you're lazy.

Tell your teacher you're gonna use Using because he forces you to use StreamReader.Peek() (is .Peek() necessary ?)

Using textIn As New StreamReader(filePath)
    Dim LineIndex As Int32 = 0
    Dim Columns As String()

    Do While textIn.Peek() <> -1
        Redim Preserve P_CODE(LineIndex)
        Redim Preserve P_DESCRIPT(LineIndex)
        ' ...
        Redim Preserve P_PRICE(LineIndex)

        Columns = textIn.ReadLine().Split(" "c)

        P_CODE(LineIndex) = Columns(0)
        P_DESCRIPT(LineIndex) = Columns(1)
        ' ...
        P_PRICE(LineIndex) = Columns(5)

        LineIndex = LineIndex + 1
    Loop
End Using ' StreamReader closed ! XD

No ! Don't ask me to use a FileStream ! I would if I know the size of each data chunck in the file and I'm using structures of fixed size. FileStream is best used when manipulating large buffer of datas as it directly works in memory with appropriate asynchronous checks.

Just to read lines ? No ! For this part, read the documentation .


String.Format()

Dim Row As String

MyListBox.Items.Clear()
For LineIndex As Int32 = 0 To P_CODE.Length - 1
    Row = String.Format("{0, -12}{1,-16}{2,10}{3,10}{4,8}{5,10}", _
              P_CODE(LineIndex), _
              P_DESCRIPT(LineIndex), _
              P_INDATE(LineIndex), _
              P_QOH(LineIndex), _
              P_MIN(LineIndex), _
              P_PRICE(LineIndex))
    MyListBox.Items.Add(Row)
Next

Write file to InventoryDataOut.txt..

Dim Separator As String = "|"
Dim FileContent As New StringBuilder() ' System.Text

' Prepare File content...
If P_CODE.Length > 0 Then
    For LineIndex As Int32 = 0 To P_CODE.Length - 2 ' Note the -2
        FileContent.AppendLine(String.Format("{0}{6}{1}{6}{2}{6}{3}{6}{4}{6}{5}", _
              P_CODE(LineIndex), _
              P_DESCRIPT(LineIndex), _
              P_INDATE(LineIndex), _
              P_QOH(LineIndex), _
              P_MIN(LineIndex), _
              P_PRICE(LineIndex), _
              Separator)))
    Next
    FileContent.Append(String.Format("{0}{6}{1}{6}{2}{6}{3}{6}{4}{6}{5}", _
              P_CODE(P_CODE.Length - 1), _
              P_DESCRIPT(P_CODE.Length - 1), _
              P_INDATE(P_CODE.Length - 1), _
              P_QOH(P_CODE.Length - 1), _
              P_MIN(P_CODE.Length - 1), _
              P_PRICE(P_CODE.Length - 1), _
              Separator)))

    ' This ensures we don't add unnecessary line at the end of the file
    ' which would make your application explode !

    ' best move is to check for null entries upon file parsing.
    ' (Again : File.ReadAllLines() + RemoveEmptyString parameter to keep it simple)

End If

' Create your file using the stream object 
' you're forced to use by your teacher,
' then dump the the content of your StringBuilder inside like
MyDummyStream.Write(FileContent.ToString())

' And close you dummy stream or use Using XD

Does your teacher has a bunch of CSV-like files which needs separator conversion from space to pipe ?

It seems he's just lazy to write the code to dispatch each column in several parallel arrays for display or other purpose. Or why would you use the space as separator upon loading the content of your file while using pipe instead to write them ?
If its a typo , just don't bother reading this. Otherwise, your teacher is just asking you to create a small program that converts the space separator to pipe... (while giving you the mission to learn manipulate (parallel) arrays, streams I/O, and String.Format)

.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM