I read strings from text file, and among the strings there is one: "15121 ♥☺020 000000/=n531☻".
I use .Contain() method to spot ♥☺☻ symbols in the string, but it doesn't recognize them. For ♥,☺,☻ I also tried \u2665, \u263a, \u263b (as arguments for .Contain()), but none of them were recognized.
Moreover, I copied the string (from console output window) and pasted it into my code to compare symbols one by one.
string s = "15121 ♥☺020 000000/=n531☻"; // the same with "15121 \u2665\u263a020 000000/=n531\u263b"
for (int j = 0; j < s.Length; j++)
{
Console.WriteLine($"{line[j]} == {s[j]}: {line[j].Equals(s[j])}");
}
This is what I got:
What may be wrong and how do I recognize those symbols?
UPDATE: The input file I read strings from is a usual text file, and the strings inside looks like these (txt opened in Notepad):
As you can see, there is THE string among the others.
I don't use any encoding when reading the txt, and to specify how I do read the file and what the line is, here is my code:
string[] lines = File.ReadAllLines(path + target_file_name);
var list = new List<string>(lines);
for (int i = 0; i < list.Count; i++)
{
string line = list[i];
if (line.Length > 21)
{
Console.WriteLine(line);
if (line.Contains("/=n")) //used just to catch THE string
{
var line_b = Encoding.Unicode.GetBytes(line);
Console.WriteLine($"{line_b} : line = {line}");
foreach (byte m in line_b)
{
Console.Write(m + " ");
}
string s = "AAXX 15121 ♥☺020 000000/=n531☻";
Console.WriteLine();
var s_b = Encoding.Unicode.GetBytes(s);
Console.WriteLine($"{s_b} : s = {s}");
foreach (byte n in s_b)
{
Console.Write(n + " ");
}
Console.WriteLine();
for (int j = 0; j < s.Length; j++)
{
Console.WriteLine($"{line[j]} == {s[j]}: {line[j].Equals(s[j])}");
}
}
Reading all the lines from txt and converting them to List is a must for me. Thus, the line is a string line from initial txt file.
I have dumped the bytes of the inout text string var b = Encoding.Unicode.GetBytes(line); and compare with my literal (#pm100), and here is the result. Not quite sure what it does give me:
I'm sorry, I'm not willing to publish my code, and I may not understand some of your suggestions for I'm not very proficient in C# (and coding in general). So I would appreciate any further help as it is, if possible.
Related
I want to include two text box texts to one text box like this
both of them are multiline.
But I want special form of include, in other words I want to include them like this
textbox 1 texts: '' help''' '' other''
textbox 2 texts:' 1' '2' '' 3''
results: help1 _ help2 _ help3
other1_other2_other3
Multiline textboxes return a string array with the lines in the Lines property. You could do something like this
string[] words = textBox1.Lines;
string[] numbers = textBox2.Lines;
var resultLines = new string[words.Length];
var sb = new StringBuilder();
for (int i = 0; i < words.Length; i++) {
sb.Length = 0; // Reset StringBuilder for the next line.
for (int j = 0; j < numbers.Length; j++) {
sb.Append(words[i]).Append("-").Append(numbers[j]).Append("_");
}
if (sb.Length > 0) {
sb.Length--; // remove the last "_"
}
resultLines[i] = sb.ToString();
}
resultsTextBox.Lines = resultLines;
First we get the words and numbers arrays. Then we create a new array for the result. Since we want a result line for each word, we make it words.Length in size.
Then we loop through the words. We use a StringBuilder to build our new lines. This is more efficient as concatenation strings with +, as it minimizes copy operations and memory allocations.
In a nested loop we put the words and numbers together.
An elegant way to solve your issue is to make use of the String.Join method in C#. I'm adding this answer because I'm a big fan of the method and think it must be part of some answer to this question because it has to do with combining strings.
Here's the code that I'd use to solve the challenge:
string[] firstInput = textBox1.Lines;
string[] secondInput = textBox2.Lines;
var combinedInputs = new string[firstInput.Length];
var combinedLine = new string[secondInput.Length];
for(int i = 0; i < firstInput.Length; i++)
{
for(int j = 0; j < secondInput.Length; j++)
{
combinedLine[j] = firstInput[i] + secondInput[j];
}
//Combine all values of combinedLine with a '-' in between and add this to combinedInputs.
combinedInputs[i] = String.Join("-", combinedLine);
}
outputTextBox.Lines = combinedInputs; //the resulting output
I hope this answer helped aswell. And I'd like to give credits to Olivier for explaining the textbox part. Another thing that I'd like to add is that this answer isn't meant to be the most efficient, but is meant to be easy to read and understand.
I am developing in C#.
I have a text file containing the following:
Sam
NYC
Mii
Peru
LEO
Argentina
I want to iterate through this file two line by two line, then print to the console the first line, second line (the Name and the Country) of each couple, so the output would be:
Sam, NYC
Mii, Peru
Here is what I have tried:
int linenum = 0;
foreach (string line in File.ReadLines("c:\\file.txt"))
{
string word = line;
string s = "";
string j = "";
linenum = linenum + 1;
if(linenum % 2 != 0) //impaire
{
s = line;
}
else
{
j = line;
}
Console.WriteLine((string.Concat(s, j));
}
But that's not working, I want to do:
int linenum = 0;
foreach( two lines in File.ReadLines("c:\\file.txt"))
{
linenum = linenum + 1;
//get the first line (linenum = 1) and store it in a string s
// then get the second line (linenum = 2) and store it in a string j
// then print the two strings together to the console like that
Console.WriteLine((string.Concat("S: " + s,"J: " j));
}
How can I do that ?
Use File.ReadAllLines to return an array of strings:
var lines = File.ReadAllLines(filePath);
for (int i = 0; i < lines.Length; i+=2)
{
var s = lines[i];
var j = lines[i+1];
Console.WriteLine($"S: {s} J: {s}");
}
You do your output with Console.WriteLine in every line, but you also should do that only for every second line. Furthermore, your variables s and j live inside the loop's scope, so they are recreated with every iteration and loose their prior value.
int i = 0; string prev = "";
foreach (string line in File.ReadLines("c:\\file.txt")) {
if (i++ % 2 == 0) prev = line;
else Console.WriteLine($"{prev}, {line}");
}
Another approach would be iterating the array you get from File.ReadAllLines with an for loop instead of foreach and increase the index by 2
var lines = File.ReadAllLines("c:\\file.txt");
//make sure, you have an even number of lines!
if (lines.Length% 2 == 0) for (int i = 0; i < lines.Length; i+=2) {
Console.WriteLine($"{lines[i]}, {lines[i+1]}");
}
You can write yourself a little helper method to return batches of lines.
This implementation handles files that are not a multiple of the batch size (2 in your case) by returning "" for the missing lines at the end of the file.
public static IEnumerable<string[]> BatchedLinesFromFile(string filename, int batchSize)
{
string[] result = Enumerable.Repeat("", batchSize).ToArray();
int count = 0;
foreach (var line in File.ReadLines(filename))
{
result[count++] = line;
if (count != batchSize)
continue;
yield return result;
count = 0;
result = Enumerable.Repeat("", batchSize).ToArray();
}
if (count > 0)
yield return result;
}
Note that this also returns a separate array for each result, in case you make a copy of it.
Given that code, you can use it like so:
foreach (var batch in BatchedLinesFromFile(filename, 2))
{
Console.WriteLine(string.Join(", ", batch));
}
Actually, you can use LINQ to get two lines in a time using Take
var twoLines = File.ReadLines(#"YourPath").Take(2));
As you can use Skip to skip the two lines you took and take the next two lines like :
var twoLines = File.ReadLines(#"YourPath").Skip(2).Take(2));
EDIT : Thanks for #derpirscher there were a performance issue so changed the code to the following :
first read the whole file and store it in a string array
then loop through it using LINQ to take two elements from the array in a time.
string[] myStringArray = File.ReadAllLines(#"YourFile.txt");
for (int i = 0; i < myStringArray.Length ; i+=2)
{
var twoLines = myStringArray.Skip(i).Take(2).ToArray();
}
Another one, using Enumerable.Repeat() and an interger selector incremented a [NumberOfLines / 2] times.
Could be interesting for the LINQ addicted (a for / foreach solution is probably better anyway).
string[] input = File.ReadAllLines([SourcePath]);
int Selector = -1;
string[] output = Enumerable.Repeat(0, input.Length / 2).Select(_ => {
Selector += 2;
return $"{input[Selector - 1]} {input[Selector]}";
}).ToArray();
The output is:
Sam NYC
Mii Peru
LEO Argentina
Use the right tool for the job. foreach() is not the right tool here.
Without giving up the memory efficiency of ReadLines() over ReadAll():
using (var lines = File.ReadLines("c:\\file.txt").GetEnumerator())
{
while (lines.MoveNext())
{
string firstLine = lines.Current;
if (!lines.MoveNext())
throw new InvalidOperationException("odd nr of lines");
string secondLine = lines.Current;
// use 2 lines
Console.WriteLine("S: " + firstLine ,"J: " + secondLine);
}
}
I want to merge 2 .txt files into one text file. Let's say I have 2 text files. First one contains 100 rows only "Try Again". Like this one in the picture:
And the second text file contains bunch of random codes:
I want to merge these 2 text files, like this one in the picture below:
I have one week and I have not figured it out yet.
Just open both files and, in a loop, read four lines from the first and one line from the second. Output each line as it's read.
using (var outputFile = File.CreateText("OutputFile.txt"))
{
using (var input1 = File.OpenText("TryAgain.txt"))
using (var input2 = File.OpenText("File2.txt"))
{
while (!input1.EndOfStream && !input2.EndOfStream))
{
int i;
for (i = 0; i < 4 && !input1.EndOfStream; ++i))
{
var s1 = input1.ReadLine();
outputFile.WriteLine(s1);
}
if (i != 4) break; // end of first file
// now read one line from the other file, and output it
var s2 = input2.ReadLine();
outputFile.WriteLine(s2);
}
}
}
This has the advantage of not having to read both files into memory all at once, and you don't have to build the entire output in memory. Each line is output immediately after it's written.
Edit: I edit the code via Jim, he warned me and now it's working.
First you need to read both files and store all lines to string array. Then loop them like down bellow. Every fifth item you need to check and write from second file.
PS: I did not try the code but prob it will work without an error.
string[] first = System.IO.File.ReadAllLines("path of first txt file");
string[] second = System.IO.File.ReadAllLines("path of second txt file");
var sb = new StringBuilder();
var k = 0;
var m = 0;
for (int i = m; i < second.Length; i++)
{
m = i + 1;
for (int j = k; j < first.Length; j++)
{
k = j + 1;
if (j != 0 && j % 4 == 0)
{
sb.Append(second[i] + "\n");
break;
}
else
{
sb.Append(first[j] + "\n");
continue;
}
}
}
// create new txt file
var file = new System.IO.StreamWriter("path of third txt file");
file.WriteLine(sb.ToString());
I have a problem with C#.
I am writing code to search a text file until it finds a certain word, then the code should move three lines and read the fourth, then continue the search to find the certain word again.
Now I don't know how to navigate through the file (forward and backward) to the line I want.
Can anybody help?
You can do something like this:
var text = File.ReadAllLines("path"); //read all lines into an array
var foundFirstTime = false;
for (int i = 0; i < text.Length; i++)
{
//Find the word the first time
if(!foundFirstTime && text[i].Contains("word"))
{
//Skip 3 lines - and continue
i = Math.Min(i+3, text.Length-1);
foundFirstTime = true;
}
if(foundFirstTime && text[i].Contains("word"))
{
//Do whatever!
}
}
// read file
List<string> query = (from lines in File.ReadLines(this.Location.FullName, System.Text.Encoding.UTF8)
select lines).ToList<string>();
for (int i = 0; i < query.Count; i++)
{
if (query[i].Contains("TextYouWant"))
{
i = i + 3;
}
}
Your requirements state that you are searching for a specific word. If that is true and you are not instead looking for a specific string, then the checked answer on this is wrong. Instead you should use:
string[] lines = System.IO.File.ReadAllLines("File.txt");
int skip = 3;
string word = "foo";
string pattern = string.Format("\\b{0}\\b", word);
for (int i = 0; i < lines.Count(); i++)
{
var match = System.Text.RegularExpressions.Regex.IsMatch(lines[i], pattern);
System.Diagnostics.Debug.Print(string.Format("Line {0}: {1}", Array.IndexOf(lines, lines[i], i) + 1, match));
if (match) i += skip;
}
If you use the string.contains method and the word you are searching for is "man", while your text somewhere contains "mantle" and "manual", the string.contains method will return as true.
When I try and run my code I get the error:
Input string was not in a correct format.
I am trying to find the largest int in each line of a text file and then add them all up.
I am sure that there are no letters in this file and everything is separated by a space.
Here is my code:
int counter = 0;
string line;
List<int> col = new List<int>();
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader(label3.Text);
while ((line = file.ReadLine()) != null)
{
int[] storage = new int[10000];
Console.WriteLine(line);
counter++;
string s = line;
string[] words = s.Split(' ');
for (int i = 0; i < words.Length; i++)
{
storage[i] = Convert.ToInt32(words[i]);
}
int large = storage.Max();
col.Add(large);
Console.WriteLine(" ");
foreach (int iii in col)
{
Console.WriteLine(iii);
}
int total = col.Sum();
Console.WriteLine(total);
}
file.Close();
// Suspend the screen.
Console.ReadLine();
It's possible that target string cannot be stored in a 32 bit integer. You can try parsing to ulong type. Take a look at Integral Types Table and Floating-Point Types Table.
Instead of doing Convert.ToInt32(), try int.TryParse(). It will return a bool value telling you if operation succeeded, and it has an out parameter where it will place result of parse operation. TryParse operation is also available on other numeric types if you decide you need them.
E.g.
int val;
string strVal = "1000";
if (int.TryParse(strVal, out val))
{
// do something with val
}
else
{
// report error or skip
}
I did a quick test and it is likely you get the error in the line
storage[i] = Convert.ToInt32(words[i]);
If so, make sure what you are trying to convert is an integer and not an empty string, for example.
I believe that the line in your code that can cause this error is
Convert.ToInt32(words[i]);
Now, when you're running this application in debug mode(which you probably are) in visual studio, you have a way to check what's going on in your program when the exception happens.
At the very very bottom of your screen is going to be some tabs. these tabs include your error list among other things. The ones I like to use are called "Locals" and "Watch". You can use the Locals tab.
When you click on the Locals tab, you should see a tree structure of all the local variables in your program. if you expand the words variable, you should see all the individual members of the array. you should also be able to see the variable i check the i'th member of your words array, and make sure that it's an integer, and not something else.
You're either converting out of size, or attempting to parse a return carriage '/r'
Make sure you're trimming your input.
My solution:
static void Main(string[] args)
{
int linecount = 100;
string path = #"C:\test\test.txt";
Random rand = new Random();
//Create File
StreamWriter writer = new StreamWriter(path, false);
for (int i = 0; i < linecount; i++)
{
for (int j = 0; j < rand.Next(10, 15); j++)
{
writer.Write(rand.Next() + " ");
}
writer.WriteLine("");
}
writer.Close();
//Sum File
long sum = Enumerable.Sum<string>(
(new StreamReader(path)).ReadToEnd().Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries),
l => Enumerable.Max(
l.Split(' '),
i => String.IsNullOrEmpty(i.Trim()) ? 0 : long.Parse(i.Trim())
)
);
}