0

Im reading a text file that consists of thousands of codes but the order of the code is as follows.

First line: NS10 EW9
Second line: $1.91
Third line: $2.60
Fourth line: 42

Im trying to split the first line into two seperate lines in the new list.

I Modified my code but there still is another error. It is an index out of range exception error.

int size = FaresFile.Length / 4 * 5;
                int linecount = 0;
                String[] split = new string[size];
                conn.ConnectionString = "Data Source=***\\*** database=***; integrated security= true";
                do
                {
                    split = FaresFile[0].Split(' ');
                    cmd.CommandText = string.Format("INSERT INTO Fares Values ('{0}','{1}', '{2}', '{3}', '{4}' )", split[linecount], split[linecount + 1], split[linecount + 2], split[linecount + 3], split[linecount + 4]);
                    cmd.Connection = conn;
                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {

                    }
                    finally
                    {
                        conn.Close();
                    }
                    linecount = linecount + 5;
                }while(linecount != split.Length);

I expected the new list to look like this.

First line: NS10
Second line: EW9
Third line: $1.91
Fourth line: $2.60
Fifth line: 42

I cannot run the program as there is an error in the code.

Smeister
  • 1
  • 3
  • Have you checked the [signature of `Split`](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?view=netframework-4.7.2)? Here's a clue a space **char** is `' '` where as a space **string** is `" "` – Liam Feb 06 '19 at 16:15
  • 1
    Look at the `String.Split` documentation (https://learn.microsoft.com/en-us/dotnet/api/system.string.split?view=netframework-4.7.2) to see what kind and type of arguments the variants (overloads) of `String.Split` accept/require. –  Feb 06 '19 at 16:16
  • I assigned it to a list because i do not know the length of the array and therefore cannot set the array length. Is there any way around that ? – Smeister Feb 06 '19 at 16:21
  • `var myArray = myString.Split(...)` will result in myArray being typed as a single-dimensioned array of string, of the right length. You could also say `string[] myArray = `. The type of an array is decided by the type of elements in the array and the number of dimensions. An instance of an array includes the number of elements as a property – Flydog57 Feb 06 '19 at 16:25
  • I have edited my code and believe the .split works now but i think there is an error in logic somewhere. – Smeister Feb 06 '19 at 16:37
  • you completely changed the code, which makes several of the answers below look silly! – Richard II Feb 06 '19 at 16:46
  • I used the answers below to help craft my updated draft as much as i am grateful i am still stumped – Smeister Feb 06 '19 at 16:48
  • what is the type of the FaresFile variable? is it a string or a FileInfo? or something else? – Richard II Feb 06 '19 at 17:16
  • FareFiles is a textfile which i used ReadAllLines to read – Smeister Feb 06 '19 at 17:26
  • so, the FaresFile variable is a String containing a filepath? – Richard II Feb 06 '19 at 17:38
  • I believe so. If i understand ReadAllLine. Each line in the text file will become a string index – Smeister Feb 06 '19 at 18:03
  • You believe so?? Don't you have access to the code? What is the TYPE of the FaresFile variable? (you know, like "linecount" is an int, "split" is a string[].) – Richard II Feb 06 '19 at 18:11
  • The farefiles variable is a string[] type – Smeister Feb 06 '19 at 18:19
  • well, one immediate problem, then, is your line that says FaresFile[0]. that means that every iteration of the loop is going to read the FIRST line of the file. Every time. – Richard II Feb 06 '19 at 18:21
  • see my answer here: https://stackoverflow.com/a/54559901/1633949. There isn't any obvious need to store the results in an intermediate string array. If you want to anyway, you can adapt my code accordingly. – Richard II Feb 06 '19 at 18:24

4 Answers4

0

I think the best would be to use two arrays. One with the source data and one that will contain the modified data.

Read the 1st line from the "source" array, split it into two and put it into the "output" array. Then copy (append) the 2nd, 3rd, 4th and 5th line of the source arra to the output array. The 6th line of the source has to be split into two lines in the output array. Then copy (append) the 7th, 8th, ...

AlexS
  • 344
  • 4
  • 14
0

I'm not sure how FaresFile is formatted, but here's some code that worked for me. (\n is newline) It seems that you want to use ' ' instead of " " so that it is interpreted literally as a character.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        string text = "NS10 EW9 \n $1.91 \n \n $2.60 \n 42";

        List<String> split = text.Split(' ').ToList();

        foreach(string item in split)
        {
            Console.WriteLine("List Item:" + item);
        }

    }
}

Depending on how your file is formatted you may need to delete empty array items.

0

(answered before the OP changed the question significantly)

Instead of fixing just the one errant line, I suggest the following approach for reading the entire file and parsing it in one statement--avoiding the loops:

using System.Linq;
using System.IO;

var allLines = File
    .ReadAllLines(filepath)
    .SelectMany(x => x.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries))
    .ToList();

where filepath is your input file.

Notes:

  • .Split here uses ' ' instead of " " (which resolves your original issue)
  • StringSplitOptions.RemoveEmptyEntries ensures that multiple consecutive spaces and any leading/trailing spaces are ignored, instead of creating blank lines in the output
Richard II
  • 853
  • 9
  • 31
  • Im using sql server does it work the same as linq? – Smeister Feb 06 '19 at 16:50
  • System.LINQ isn't a DB, it's a set of extension methods that allow you to work with enumerables (like arrays and lists). you can do whatever you want with allLines in my answer, including inserting the data into a SQL table. (I'm going to create another answer based on your revisions to your question.) – Richard II Feb 06 '19 at 17:07
  • Yes please do I am still stumped on how to use this linq – Smeister Feb 06 '19 at 17:21
  • here: https://stackoverflow.com/a/54559901/1633949 – Richard II Feb 06 '19 at 18:12
0
string inputFile = "{filepath to your input file}";
using (var conn = new SqlConnection())
{
    conn.ConnectionString = "{your connection string}";
    conn.Open();
    File.ReadAllLines(inputFile)
        .SelectMany(l => l.Split(new[] { ' '}, StringSplitOptions.RemoveEmptyEntries))
        .Select(l => $"INSERT INTO Fares  Values ('{l}')")
        .ToList()
        .ForEach(c =>
        {
            using (var cmd = new SqlCommand(c, conn))
            {
                cmd.ExecuteNonQuery();
            }
        });
}

The important differences from your code here are:

  1. Inserts one SQL row at a time. You were trying to insert 5 at a time, but the SQL syntax wasn't correct. I assume you were trying to reduce the total number of SQL commands issued, but it was muddying the issue. Get it working simply first.
  2. Uses LINQ to make the code more concise.
  3. Uses SelectMany() to accomplish your main stated objective (treating multiple tokens on one line of input as though they are individual lines). SelectMany() flattens multiple collections into a single collection.
  4. Uses the "using" statement so you get free close/disposal of your SqlConnection and SqlCommand objects.
  5. Dispenses with the intermediate FaresFile string array
Richard II
  • 853
  • 9
  • 31
  • I just finished running your code. The program has been running for quite a while already but my display is not loading. Is it supposed to take this long – Smeister Feb 06 '19 at 18:46
  • What do you mean by "my display is not loading"? Display of what? Your question is just a general debugging one. I can't possibly answer it without knowing the size of your input, the latency of your network connection, etc.Try putting debug output statements that include a timestamp and the value your are writing, immediately before and after the "cmd.ExecuteNonQuery()" to see what's going on. Also, check your DB table to see how many rows have been inserted already. Dig in for yourself and figure out where the problem is occurring. – Richard II Feb 06 '19 at 19:38
  • e.g. Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}; start; {cmd.CommandText}"); cmd.ExecuteNonQuery(); Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}; end; {cmd.CommandText}"); – Richard II Feb 06 '19 at 19:45