Parse text and save in memory c# - c#

I have such text
5 1 5 1 5 1 5 1
1
I must get
5 1 5 1 5 1 5 1
0 1 0 0 0 0 0 0
and save it in memory. But when i use such consruction:
List<string> lines=File.ReadLines(fileName);
foreach (string line in lines)
{
var words = line.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach(string w in words)
Console.Write("{0,6}", w);
// filling out
for (int i = words.Length; i < 8; i++)
Console.Write("{0,6}", "0.");
Console.WriteLine();
}
I only print text in desired format on display.
How I can save it in List<string> newLines?

If we assume the data is meant to be equally spaced (as suggested by your current Write etc, then I would process it as characters:
char[] chars = new char[49];
foreach(string line in File.ReadLines(path))
{
// copy in the data and pad with spaces
line.CopyTo(0, chars, 0, Math.Min(line.Length,chars.Length));
for (int i = line.Length; i < chars.Length; i++)
chars[i] = ' ';
// check every 6th character - if space replace with zero
for (int i = 1; i < chars.Length; i += 6) if (chars[i] == ' ')
chars[i] = '0';
Console.WriteLine(chars);
}
Or if you really need it as lines, use (at the end of each loop iteration):
list.Add(new string(chars));

I assume there is exactly 5 space between numbers. So here is the code:
List<string> lines = System.IO.File.ReadLines(fileName).ToList();
List<string> output = new List<string>();
foreach (string line in lines)
{
var words =
line.Split(new string[] { new string(' ', 5) },
StringSplitOptions.None).Select(input => input.Trim()).ToArray();
Array.Resize(ref words, 8);
words = words.Select(
input => string.IsNullOrEmpty(input) ? " " : input).ToArray();
output.Add(string.Join(new string(' ', 5), words));
}
//output:
// 5 1 5 1 5 1 5 1
// 0 1 0 0 0 0 0 0

You can use this code for producing your desired result :
StreamReader sr = new StreamReader("test.txt");
string s;
string resultText = "";
while ((s = sr.ReadLine()) != null)
{
string text = s;
string[] splitedText = text.Split('\t');
for (int i = 0; i < splitedText.Length; i++)
{
if (splitedText[i] == "")
{
resultText += "0 \t";
}
else
{
resultText += splitedText[i] + " \t";
}
}
resultText += "\n";
}
Console.WriteLine(resultText);
"test.txt" is the text file that contains your text and "resultText" variable contains the result that you want.

Related

c# Splitting string to a multi dimensional array?

I encountered a little problem that i can't get my head around.
I have normal string[] array with a text import in it. Every row is stored in separate under every index.
A row usually look something like this:
string[i] = |title1|title2|title3|title4|title5|
string[i+1] = |Word1|Word2|Word3|Word4|Word5|
I want to split these rows and put them in a multi dimensional array.
Already counted how I have to declare the dimensions of the array.
I want to split it now. I was thinking about going through the normal array with two loops and look for the separator while saving the words in a string then copying it to the multi array.
Do you guys have any idea how could i do that, because this is too much hassle for such a small thing.
I want the multi array look something like this:
string[0,0] = title1,
string[0,1] = title2 etc.
string[1,0] = word1
string[1,1] = word2
This is the code that creates the array:
public string [,] SplitArrays(string [] arrayin)
{
long columns = 0;
char line = '|';
string row;
for(int i = 0; i < arrayin.Length;i++)
{
row = arrayin[i];
if (Convert.ToChar(row.Substring(0, 1)) == line)
{
for(int j = 0; j < row.Length;j++)
{
if (Convert.ToChar(row.Substring(j,(j+1))) == line)
{
columns++;
}
}
}
break;
}
int rowlength = arrayin.Length;
string[,] finalarray = new string[columns,rowlength];
And this is how far I got with separating, but I got kind of confuse and I probably messed it up:
int rowcolumncount = 0;
string word = "";
bool next = false;
for(int k = 0; k < arrayin.Length; k++)
{
row = arrayin[k];
for(int l = 0; l < row.Length; l++)
{
if (Convert.ToChar(row[l]) == line)
{
for(int z = 0; next == false;)
{
if(row[z] == line)
{
next = true;
}
else
{
string part = Convert.ToString(row[z]);
word = string.Join("",part);
}
finalarray[l, rowcolumncount] = word;
rowcolumncount++;
}
}
rowcolumncount = 0;
}
}
return finalarray;
}
The main array contains around 12000 lines.
Thank you!
You can try something like this: Split each item with arrayin by | and write these chunks into a line of 2D array:
public string[,] SplitArrays(string[] arrayin) {
if (null == arrayin)
return null;
else if (arrayin.Length <= 0)
return new string[0, 0];
// null : we don't know size (number of columns) before 1st line split
string[,] result = null;
int row = 0;
foreach (var line in arrayin) {
string[] items = line.Split('|');
// - 2 : skip the very first and the very last items which are empty
if (null == result)
result = new string[arrayin.Length, items.Length - 2];
// if line is too short, let's pad result with empty strings
for (int col = 0; col < result.GetLength(1); ++col)
result[row, col] = col + 1 < items.Length - 1
? items[col + 1]
: ""; // padding
row += 1;
}
return result;
}
Usage:
string[] source = new string[] {
"|title1|title2|title3|title4|title5|",
"|Word1|Word2|Word3|Word4|Word5|",
};
// {
// {"title1", "title2", "title3", "title4", "title5"},
// { "Word1", "Word2", "Word3", "Word4", "Word5"}
// }
string[,] array = SplitArrays(source);
If the number of items per line vary, you can use a jagged array.
We create the empty array and set the row count size.
Then we parse all lines of the list and for all line we split it to have desired items to add them into the dimension as we resize the row sub-array.
static public void Test()
{
var list = new string[]
{
"| title1 | title2 | title3 | title4 | title5 |",
"| Word1 | Word2 | Word3 | Word4 | Word5 |"
};
int indexD1 = 0;
string[][] result = null;
Array.Resize(ref result, list.Length);
foreach ( string item in list )
{
var str = item;
str = str.TrimStart('|').TrimStart();
str = str.TrimEnd('|').TrimEnd();
str = str.Replace(" | ", "|");
var items = str.Split('|');
Array.Resize(ref result[indexD1], items.Length);
int indexD2 = 0;
foreach ( string part in items )
result[indexD1][indexD2++] = part;
indexD1++;
}
foreach ( var row in result )
{
foreach ( var str in row )
Console.WriteLine(str);
Console.WriteLine();
}
}
You can also use a List of List of Strings and use the method Add():
var result = new List<List<string>>();

C# IF statement is not excluding strings

So the problem is : I want to read from file and exclude certain strings( i am inexperienced so I decided to use IF so i want to exclude the strings Name, facultyNumber and etc. but it doesn't exclude them for some reason ? (I've tried to remove the spaces from the if statement)
public void read()
{
string[] textes = File.ReadAllLines(#"C:\Users\sashk\Source\Repos\ConsoleApp6\ConsoleApp6\save.txt", Encoding.Default);
double[] gread = new double[] { 1, 2, 3 };
List<string> texts = new List<string>();
int i= 0;
int z = 0;
foreach (string text in textes)
{
string[] words = textes[i].Split(' ');
for (int j = 0; j < words.Length; j++)
{
if (!words[j].Equals(" Name: ") || !words[j].Equals(" FacultyNumber: ") || !words[j].Equals(" Grades: ") || !words[j].Equals(" AverageGrade: "))
{
texts.Add(words[j]);
}
}
// for (int j = 2; j < texts.Count; j++)
// {
// gread[z] = Convert.ToDouble(texts[j]);
// }
// addStudent(texts[0], Convert.ToInt32(texts[1]), gread);
for (int j = 0; j < 40; j++)
{
Console.WriteLine(texts[j]);
}
i++;
}
The content of the file is this:
> Name: asd FacultyNumber: 2 Grades: 1,23 4,56 7,89 AverageGrade: 4,56
Name: as FacultyNumber: 4 Grades: 1 5 9 AverageGrade: 5
Name: ad FacultyNumber: 3 Grades: 2 4 7 AverageGrade: 4,33333333333333
Name: ddd00 FacultyNumber: 1 Grades: 12 15 99 AverageGrade: 42
You can use Contains like this:
var excluded = new[] { "Name:", "FacultyNumber:", "Grades:", "AverageGrade:" };
foreach (string text in textes)
{
string[] words = textes[i].Split(' ');
for (int j = 0; j < words.Length; j++)
{
if (!excluded.Contains(words[j]))
{
texts.Add(words[j]);
}
}
}
But I think you can do it with LINQ. The code will be much cleaner:
string[] textes = File.ReadAllLines(#"C:\Users\sashk\Source\Repos\ConsoleApp6\ConsoleApp6\save.txt", Encoding.Default);
var excluded = new[] { "Name:", "FacultyNumber:", "Grades:", "AverageGrade:" };
var texts = textes.SelectMany(x => x.Split(' ').Where(y => !excluded.Contains(y)));
foreach(string word in texts)
{
Console.WriteLine(word);
}
I'm fairly new to programming and don't know if there's any downside to using the string.Replace method, but this is how I would do it.
public void read()
{
string[] textes = File.ReadAllLines(#"C:\Users\sashk\Source\Repos\ConsoleApp6\ConsoleApp6\save.txt", Encoding.Default);
List<string> texts = new List<string>();
for (int i = 0; i < textes.Lenght; i++)
{
texts.Add(textes[i].Replace(" Name: ", ""));
texts.Add(textes[i].Replace(" FacultyNumber: ", ""));
texts.Add(textes[i].Replace(" Grades: ", ""));
texts.Add(textes[i].Replace(" AverageGrade: ", ""));
}
foreach (string text in texts)
{
Debug.WriteLine(text);
}
}
You should && all conditions. As the preference of || is from left to right, if the most left condition would be true the other conditions will not be considered. Hence, if a word passed this part of condition !words[j].Equals(" Name: "), it will pass the whole of the condition. Therefore, if there is a word likes FacultyNumber or Grades passed the first condition and you will not get what you specified. You can modify your code likes the following:
if (!(words[j].Equals(" Name: ") ||
words[j].Equals(" FacultyNumber: ") ||
words[j].Equals(" Grades: ") ||
words[j].Equals(" AverageGrade: ")))

C# - Split at 20 characters but not if it is in between a word

I want to split a string into smaller parts, not exceeding a string length of 20 characters.
The current code is able to split an input string into an array of strings of length 20. However, this could cut a word.
The current code is:
string[] Array;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (i % 20 == 0 && i != 0) {
sb.Append('~');
}
sb.Append(input[i]);
}
Array = sb.ToString().Split('~');
For an input of this: Hello. This is a string. Goodbye., the output would be ['Hello. This is a str', 'ing. Goodbye.'].
However, I don’t want the string to be cut if it’s a word. That word should move to the next string in the array. How can I get the following output instead?
['Hello. This is a', 'string. Goodbye.']
First split your sentence on word-boundary:
var words = myString.Split();
Now concatenate words as long as not more than 20 characters are within your current line:
var lines = new List<string> { words[0] };
var lineNum = 0;
for(int i = 1; i < words.Length; i++)
{
if(lines[lineNum].Length + words[i].Length + 1 <= 20)
lines[lineNum] += " " + words[i];
else
{
lines.Add(words[i]);
lineNum++;
}
}
Here is a fiddle for testing: https://dotnetfiddle.net/s0LrFC
Could be more elegant but this will split the string to lines of a maximum number of characters. The words will be kept together unless they exceed the given length.
public static string[] SplitString(string input, int lineLen)
{
StringBuilder sb = new StringBuilder();
string[] words = input.Split(' ');
string line = string.Empty;
string sp = string.Empty;
foreach (string w in words)
{
string word = w;
while (word != string.Empty)
{
if (line == string.Empty)
{
while (word.Length >= lineLen)
{
sb.Append(word.Substring(0, lineLen) + "~");
word = word.Substring(lineLen);
}
if (word != string.Empty)
line = word;
word = string.Empty;
sp = " ";
}
else if (line.Length + word.Length <= lineLen)
{
line += sp + word;
sp = " ";
word = string.Empty;
}
else
{
sb.Append(line + "~");
line = string.Empty;
sp = string.Empty;
}
}
}
if (line != string.Empty)
sb.Append(line);
return sb.ToString().Split('~');
}
To test:
string[] lines = SplitString("This is a test of the string splitter KGKGKJGKGHKJHJKJKHGJHGhghsjagsjasgajsgjahs yes!", 20);
foreach (string line in lines)
{
Console.WriteLine(line);
}
Output:
This is a test of the
string splitter
KGKGKJGKGHKJHJKJKHGJ
HGhghsjagsjasgajsgja
hs yes!
I believe it's faster to split it only at places where it needs to be, instead of every word. With lines.SelectMany(x => Split(x, 80) can be used with multiline texts:
private static IEnumerable<string> Split(string text, int maxLength)
{
var i = 0;
while (i + maxLength < text.Length)
{
var partIndex = text.LastIndexOf(' ', i + maxLength, maxLength);
if (partIndex == -1)
partIndex = i + maxLength;
yield return text[i..partIndex];
i = partIndex + 1;
}
yield return text[i..];
}

Convert string from text file to integer array

I wrote this code in order to open a text file in a C# language
Each line in the file contains five digits such as
0 0 2 3 6
0 1 4 4 7
0 2 6 9 9
1 0 8 11 9
1 1 12 15 11
2 2 12 17 15
The distance between the number and the other is one tab
The problem is when you execute the program this error appears
input string was not in correct format in Convert.ToInt32(t[j])
code:
string[] st = File.ReadAllLines("C:\\testing\\result.txt");
int[,] tmp = new int[st.Length - 1, 5];
for (int i = 1; i < st.Length; i++)
{
string[] t = st[i].Split(new char[] { ' ' });
int cnt = 0;
for (int k = 0; k < t.Length; k++)
if (t[k] != "")
{ t[cnt] = t[k]; cnt++; }
for (int j = 0; j < 5; j++)
tmp[i - 1, j] = Convert.ToInt32(t[j]);
}
How can i correct that?
I suggest changing the collection type from 2d array int[,] into jagged one int[][] and then use Linq:
using System.Linq;
...
int[][] data = File
.ReadLines(#"C:\testing\result.txt")
.Select(line => line
// Uncomment this if you have empty lines to filter out:
// .Where(line => !string.IsNullOrWhiteSpace(line))
.Split(new char[] {'\t'}, StringSplitOptions.RemoveEmptyEntries)
.Select(item => int.Parse(item))
.ToArray())
.ToArray();
split char should be a tab character '\t' instead of single space
You have five numbers per row, but not necessarily five digits. You will need a more complex solution, like this:
string[] st = File.ReadAllLines("C:\\testing\\result.txt");
int[,] tmp = new int[st.Length - 1, 5];
bool isAlreadyNumber = false;
bool isEmptyRow = true;
int rowIndex = -1;
int colIndex = -1;
for (int i = 0; i < st.Length; i++) {
isAlreadyNumber = false;
isEmptyRow = true;
foreach (char c in st[i]) {
if ((c >= '0') && (c <= '9')) {
if (isAlreadyNumber) {
tmp[rowIndex][colIndex] = tmp[rowIndex][colIndex] * 10 + (c - '0');
} else {
tmp[rowIndex][colIndex] = c - '0';
if (isEmptyRow) rowIndex++;
isEmptyRow = false;
isAlreadyNumber = true;
}
} else {
isAlreadyNumber = false;
}
}
}
Note, that the indexing was fixed. This untested code handles other separators and empty lines as well, but still assumes there will be five numbers.

How to replace space/character with specified character after first numeric value in string using C#?

I have String containing Special Characters & Numeric Values .
Eg:
3-3 3
3-3"3/4
3-3-3/4
3-3 3/4
3 3 3
3'3 3
Output must be:
3f3 3
3f3"3/4
3f3-3/4
3f3 3/4
3f3 3
3f3 3
I have tried using :
public static string ReplaceFirst(string text, string search, string replace)
{
int pos = text.IndexOf(search);
if (pos < 0)
{
return text;
}
return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}
using above code it replaces the first occurrence with specified character this works fine.
Eg: 3-3 3 Output: 3f3 3
But for 3 3-3 Output: 3 3f3 according to code is correct. but i want to replace space/character after first numeric which would be 3f3-3
Help Appreciated!
Simple loops should work.
for(int i =0; i < myListOfStrings.Count; i++)
{
char[] chars = myListOfStrings[i].ToCharArray();
for (int j = 0; j < chars.Count(); j++)
{
if (Char.IsDigit(chars[j]))
{
if(j + 1 < chars.Count())
{
chars[j + 1] = 'f'; //'f' being your replacing character
myListOfStrings[i] = new string(chars);
}
break;
}
}
}
Output examples
myListOfStrings.Add("3-3 3");
myListOfStrings.Add("3-3-3/4");
myListOfStrings.Add("3 3-3");
myListOfStrings.Add("3 3 3");
3f3 3
3f3-3/4
3f3-3
3f3 3
Update from comments
for (int i = 0; i < myListOfStrings.Count; i++)
{
char[] chars = myListOfStrings[i].ToCharArray();
for (int j = 0; j < chars.Count(); j++)
{
if (!Char.IsDigit(chars[j]))
{
if (j + 1 < chars.Count())
{
chars[j] = 'f'; //'f' being your replacing character
myListOfStrings[i] = new string(chars);
}
break;
}
}
}
var match = Regex.Match(text, search); //To search for any special character, use #"\W" as the second parameter
var editable = text.ToCharArray();
editable[match.Index] = replace[0];
text = new String(editable);
return text;
Following worked for me:
Modified Code:
string S="10-3 3";
char[] chars = S.ToCharArray();
for (int j = 0; j < chars.Count(); j++)
{
if (Char.IsDigit(chars[j]))
{
}
else
{
if (j + 1 < chars.Count())
{
chars[j] = 'f'; //'f' being replacing character
S = new string(chars);
}
break;
}
}
Output: 10f3 3

Categories