Saving Text to array - c#

I have been using this link as an example, but have been having troubles with it:
2d Array from text file c#
I have a textfile that contains :
1 1 0 0
1 1 1 0
0 0 0 1
0 1 0 0
And I'm trying to use the function:
static void Training_Pattern_Coords()
{
String input = File.ReadAllText(#"C:\Left.txt");
int i = 0, j = 0;
int[,] result = new int[4, 4];
foreach (var row in input.Split('\n'))
{
j = 0;
foreach (var col in row.Trim().Split(' '))
{
result[i, j] = int.Parse(col.Trim());
j++;
}
i++;
}
Console.WriteLine(result[1, 3]);
Console.ReadLine();
}
However I keep getting the error message (Input String was not in correct format) at the line :
foreach (var row in input.Split('\n'))
I think it has something to do with the spaces within the textfile but I'm not entirely sure. Thanks for your help!

Instead of File.ReadAllText use File.ReadLines.By doing that you won't need to use Split('\n').
int[,] result = new int[4, 4];
var lines = File.ReadLines(#"C:\Left.txt")
.Select(x => x.Split()).ToList();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
result[i, j] = int.Parse(lines[i][j]);
}
}

Try ReadAllLines as opposed to ReadAllText

Replace any \r (carriage return)
input = input.Replace('\r',' ');

Replace your \r to "\r\n"
Try this:
foreach (var row in input.Split("\r\n"))

Related

C#: Read a text file into a 2D char array

Like I mentioned above, I try to read a text file into a 2D char array.
That's my file:
abcde
fghij
klmno
pqrst
uvwxy
and that's my code:
var path = #"C:text.file";
StreamReader sr = File.OpenText(path);
{
char[,] arr = new char[5, 5];
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
arr[i, j] = (Char)sr.Read();
Console.WriteLine(arr[i, j] + " = {0},{1}", i,j);
}
}
Console.WriteLine(arr[2,1]);
}
}
and at least my output:
1 = 0,0
2 = 0,1
3 = 0,2
4 = 0,3
5 = 0,4
= 1,0
= 1,1
6 = 1,2
7 = 1,3
8 = 1,4
9 = 2,0
0 = 2,1
= 2,2
...
so my question is, why e.g. arr[1,0] or arr[1,1] is empty?
thanks for your help!
sno0z3
The problem is caused by the presence of a newline at the end of each line (and a newline is composed of two characters in a Windows text file).
So you can check for these characters before adding to your array, or simply read the line (thus removing the newline) and then loop over the string obtained extracting char by char and adding them to your array
char[,] arr = new char[5, 5];
for (int i = 0; i < 5; i++)
{
string curLine = sr.ReadLine();
for (int j = 0; j < curLine.Length; j++)
{
arr[i, j] = curLine[j];
Console.WriteLine(arr[i, j] + " = {0},{1}", i,j);
}
}

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.

Text bombardment

this is the program I'm trying to write:
Write a program that reads a text and line width from the console. The program should distribute the text so that it fits in a table with a specific line width. Each cell should contain only 1 character. It should then read a line with numbers, holding the columns that should be bombarded.
My code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _04.Text_Bombardment
{
class Program
{
static void Main(string[] args)
{
var sentence = Console.ReadLine();
var bombing = int.Parse(Console.ReadLine());
var selected = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
Dictionary<int, bool> bombDict = new Dictionary<int, bool>();
var newSentence = sentence + new string(' ', bombing - sentence.Length % bombing); // whole row minus words left
for (int i = 0; i < selected.Length; i++)
{
bombDict.Add(selected[i], true);
}
var rows = newSentence.Length / bombing;
var cols = bombing;
var count = 0;
var arrSent = newSentence.ToCharArray();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (bombDict.ContainsKey(j) && bombDict[j] == true && arrSent[count] != ' ')
{
arrSent[count] = ' ';
try
{
if (arrSent[count + bombing] == ' ')
{
bombDict[j] = false;
}
else
{
bombDict[j] = true;
}
}
catch (IndexOutOfRangeException)
{
continue;
}
}
count++;
}
}
var finalSent = string.Join("", arrSent).TrimEnd();
Console.WriteLine(finalSent);
}
}
}
And it breaks on this sentence:
Vazov received his elementary education in hisnative town of Sopoandat Plovdiv. The son of a conservative, well-to-do merchant.
20
1 6 17 2 5 0 15
Current Output:
ov eceived i e en ry educa i n hi ative to n of opo dat Plov iv. T e s of a co serva ive well-to- o mer ha t.
Intended Output:
ov eceived i e en ry educa i n hi ative to n of opo dat Plov iv. T e s of a co serva ive well-to- o mer han .
Soo it only doesn't work on the end.
Can someone help me?
Any suggestions?
Additional notes:
For example, we read the text "Well this problem is gonna be a ride." and line width 10. We distribute the text among 4 rows with 10 columns. We read the numbers "1 3 7 9" and drop bombs on those columns in the table.
The bombs destroy the character they fall on + all the neighbouring characters below it.
Note: Empty spaces below destroyed characters stop the bombs (see column 7).
Finally, we print the bombarded text on the console: "W l th s p o lem i o na be a r de."
Note: The empty cells in the table after the text should NOT be printed.
Your solution is very difficult to understand, keep it simple give names to the variables that you can understand easily.
I modified your code, hope it helps you:
static void Main()
{
string sentence = "Well this problem is gonna be a ride.";
int numberOfColumns = int.Parse("10");
List<int> bombs = "1 3 7 9".Split(' ').Select(int.Parse).ToList();
// we need to convert to decimal, otherwise C# will ignore decimal part.
//example: 127/20 = 6.35, so we need 7 rows. if we don't convert to decimal we have 6
// the Ceiling says, always round up. so even 6.1 will be rounded to 7
int numberOfRows = (int)Math.Ceiling(sentence.Length / Convert.ToDecimal(numberOfColumns));
char[,] array = new char[numberOfRows, numberOfColumns];
int sentencePointer = 0;
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
// if you want to print the grid with the full text, just comment the 3 lines below,
//and keep only "array[rowIndex, colIndex] = sentence[sentencePointer];"
if (bombs.Contains(colIndex))
{
if (sentence[sentencePointer] == ' ') // bomb is deactivated
{
bombs.Remove(colIndex);
array[rowIndex, colIndex] = sentence[sentencePointer];
}
else
array[rowIndex, colIndex] = '*'; // * represents a bomb
}
else
array[rowIndex, colIndex] = sentence[sentencePointer];
sentencePointer++; // move next character
if (sentencePointer >= sentence.Length)
break; // we reach the end of the sentence.
}
}
PrintGrid(array, numberOfRows, numberOfColumns);
// just give some space to print the final sentence
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
Console.Write(array[rowIndex, colIndex]);
}
}
Console.ReadKey();
}
private static void PrintGrid(char[,] array, int numberOfRows, int numberOfColumns)
{
Console.WriteLine(new string('-', numberOfColumns * 2));
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
Console.Write("|");
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
Console.Write(array[rowIndex, colIndex]);
Console.Write("|");
}
Console.WriteLine("");
}
}
Somewhat more elegant solution.
private static IEnumerable<char> Bomb(IEnumerable<char> text, IEnumerable<int> indexes, int length)
{
var indexArray = new List<int>(indexes);
var used = new object[length];
return text.Select(
(c, index) =>
{
if (c != ' ' && indexArray.Contains(index % length))
{
used[index % length] = new object();
return '\0';
}
if (c == ' ' && used[index % length] != null)
{
indexArray.Remove(index % length);
}
return c;
});
}

convert Text file 2D array to integer 2D array

I am trying to use data from text file (matrix [i, j]). I have code works with one dimension array but doesn't work with two dimension array. I tried to use different method but I always get an error.
string fileContent = File.ReadAllText(file path);
string[] integerStrings = fileContent.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
integers = new int[integerStrings.Length];
for (int n = 0; n < integerStrings.Length; n++)
integers[n] = int.Parse(integerStrings[n]);
I modify it to this
string fileContent = File.ReadAllText(path);
string[,] integerStrings = fileContent.Split(new char[,] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
integers = new int[integerStrings.Length,2];
for (int n = 0; n < integerStrings.Length; n++)
for (int j = 0; j <2; n++)
integers[n,j] = int.Parse(integerStrings[n,j]);
the text file
0 0
2 0
4 0
6 0
8 1
10 1
12 1
14 2
16 3
18 3
Note the code I need should be fixable with rows number
get the lines from the file then split each line to get your 2d array. Here is a rough first draft. You can test and refactor to improve on it if needed.
int[,] matrix = null;
int rowCount = 0;
int colCount = 0;
var lines = File.ReadAllLines(path);
rowCount = lines.Length;
for(int i = 0; i < rowCount; i++) {
var line = lines[i];
var tokens = line.Split(new []{' ', '\t'}, StringSplitOptions.RemoveEmptyEntries);
if(matrix == null) {
colCount = tokens.Length;
matrix = new int[rowCount, colCount];
}
for(int j = 0; j < colCount; j++) {
matrix[i, j] = int.Parse(tokens[j]);
}
}
this part is for display the matrix
int rowLength = matrix.GetLength(0);
int colLength = matrix.Rank;
for (int i = 0; i < rowLength; i++) {
for (int j = 0; j < colLength; j++) {
Console.Write(string.Format("{0} ", matrix[i, j]));
}
Console.WriteLine();
Console.WriteLine();
}
Console.ReadLine();
If you want 2d array split method just gives 1d array so you have to split twice...
First split by line breaks then by spaces...
string[] rows = fileContent.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int[,] result = new int[rows.Length,2];
for(int i = 0; i < rows.Length; i++)
{
var col = rows[i].Split(new char{' ','\t'}, StringSplitOptions.RemoveEmptyEntries);
result[i,0] = int.Parse(col[0]);
result[i,1] = int.Parse(col[1]);
}

how to read matrix row elements in single line in C# console

I want to read a 5 X 5 matrix from input in console and I want to read row elements in a single line and not in separate lines, like this:
25 16 14 12
10 15 11 10
2 10 9 8 8
7 6 11 20
5 4 1 0 3
Multi line version:
private static int[,] ReadMatrix()
{
var mtr = new int[5, 5];
for (var i = 0; i < 5; i++)
{
var line = Console.ReadLine();
var spl = line.Split(' ');
if (spl.Length != 5) throw new FormatException();
for (var j = 0; j < 5; j++)
mtr[i, j] = int.Parse(spl[j]);
}
return mtr;
}
Single line version:
private static int[,] ReadMatrix()
{
var mtr = new int[5, 5];
var line = Console.ReadLine();
if (string.IsNullOrWhiteSpace(line)) throw new FormatException();
var spl = line.Split(' ');
if (spl.Length != 25) throw new FormatException();
for (var i = 0; i < 25; i++)
mtr[i/5, i%5] = int.Parse(spl[i]);
return mtr;
}
I think this could help: reading two integers in one line using C#
Basicly the string[] tokens = Console.ReadLine().Split(); and then you could call tokens.Length to see how many columns there r going to be.
i used this function to read elements
static int readIndex()
{
string num = string.Empty;
ConsoleKeyInfo cr;
do
{
cr = Console.ReadKey(true);
int n;
if (int.TryParse(cr.KeyChar.ToString(), out n))
{
num += cr.KeyChar.ToString();
Console.Write(cr.KeyChar.ToString());
}
else if (cr.Key == ConsoleKey.Backspace)
{
if (num.Length > 0)
{
Console.Write("\b");
num = num.Remove(num.Length - 1);
}
}
} while (cr.Key != ConsoleKey.Enter);
Console.Write(" ");
return int.Parse(num);
}
then we need just a loop to read elements like this
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
mat[i, j] = (int)readIndex();
}
Console.WriteLine();
}

Categories