I want to check if a string from the first line of a file, is equal with an another string.
The awkward part is that, the strings are the same, but my program doesn't return a true value.
The string is teach and the first line of the file is teach too.
string date = System.IO.File.ReadAllText(folder + "/NPC/" + score_npc + "/" + score_npc + ".txt" );
if (condition)
{
string[] parametrii = date.Split('\n');
if (parametrii[0].Equals("teach"))
//instructions
I tried all the compare methods, i made my own function too. And my function said me that the (parametrii[0])[0] == b
Here is how the file looks like:
teach
poza1
poza2
end
That's propably because new line character is not \n in the file. It may be \r\n instead.
Try File.ReadAllLines instead:
string[] lines = System.IO.File.ReadAllLines(folder + "/NPC/" + score_npc + "/" + score_npc + ".txt" );
if (condition)
{
if (lines[0].Equals("teach"))
// instructions
}
Edit
As Grant Winney suggests, if you only need to manipulate first line (or not all of the) file, you may use File.ReadLines:
string firstLine = File.ReadLines(path).First();
instead.
Have u tried to change
string[] parametrii = date.Split('\n');
into
string[] parametrii = date.Split(Environment.NewLine);?
I suspect it's because your strings contain '\r' character
Related
I have this code written in C# but looks kind of "bad" and I would like to shorten it somehow and keep it clean and simple.
All this code works pretty fine but I want to know if there's any other way I can achieve the same thing.
EDIT: I forgot to mention that the firstLine has a bad date format attached with it, so it is like this: "This_is_my_first_line_20220126". So I split the string and then only join it with the corrected date. The problem is that I can never know how long the new string would be and I don't want to handle the code like this and go up to 100 parts.
Here's my code:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
string firstLine = lines.FirstOrDefault();
//note: firstLine looks like this: This_is_my_first_line_20220126
string[] sub = firstLine.Split('_');
string name="";
if(sub.Length==2)
name = sub[0]+"_"+sub[1]+"_"+correctDate;
else if(sub.Length==3)
name = sub[0]+"_"+sub[1]+"_"+sub[2]+"_"correctDate;
...
else if(sub.Length==20)
name = sub[0]+"_"+ ... "_" + sub[19];
Now, my final name value should be "This_is_my_line_26012022" but I want it to depend on the length of the given string. So far I know that the maximum length would go up to 20 but I don't want my code to look like this. Can I shorten it somehow?
you can find the LastIndexOf the underscore and drop the date by using Substring:
string firstLine = "This_is_my_first_line_20220126";
string correctDate = "26012022";
string correctString = firstLine.Substring(0, firstLine.LastIndexOf("_") + 1) + correctDate;
Still a little perplexed with the split aproach, but this a way to join back all elements
string name = string.Join("_", sub.Take(sub.Length - 1).Append(correctDate));
Or use the substring method (and no need of all that split & join)
name = firstLine.Substring(0, firstLine.LastIndexOf("_") +1) + correctDate;
I forgot to mention that firstLine has a bad date format like "This_is_my_Line_20220125"
If you want to correct just the first line:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
lines[0] = lines[0][..^8] + correctDate;
[..^8] uses C# 9's "indices and ranges" feature, that allows for a more compact way of taking a substring. It means "from the start of the string, up to the index 8 back from the end of the string".
If you get a wiggly line and possibly a messages like "... is not available in C# version X" you can use the older syntax, which would be more like lines[0] = lines[0].Remove(lines[0].Length - 8) + correctDate;
If you want to correct all lines:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
for(int x = 0; x < lines.Length; x++)
lines[x] = lines[x][..^8] + correctDate;
If the incorrect date isn't always 8 characters long, you can use LastIndexOf('_') to locate the last _, and snip it to that point
I'm having two problems with reading my .csv file with streamreader. What I'm trying to do is get the values, put them into variables which I'll be using later on, inputting the values into a browser via Selenium.
Here's my code (the Console.Writeline at the end is just for debugging):
string[] read;
char[] seperators = { ';' };
StreamReader sr = new StreamReader(#"C:\filename.csv", Encoding.Default, true);
string data = sr.ReadLine();
while((data = sr.ReadLine()) != null)
{
read = data.Split(seperators);
string cpr = read[0];
string ydelsesKode = read[1];
string startDato = read[3];
string stopDato = read[4];
string leverandoer = read[5];
string leverandoerAdd = read[6];
Console.WriteLine(cpr + " " + ydelsesKode + " " + startDato + " " + stopDato + " " + leverandoer + " " + leverandoerAdd);
}
The code in and of itself works just fine - but I have two problems:
The file has values in Danish, which means I get åøæ, but they're showing up as '?' in console. In notepad those characters look fine.
Blank values also show up as '?'. Is there any way I can turn them into a blank space so Selenium won't get "confused"?
Sample output:
1372 1.1 01-10-2013 01-10-2013 Bakkev?nget - dagcenter ?
Bakkev?nget should be Bakkevænget and the final '?' should be blank (or rather, a bank space).
"Fixed" it by going with tab delimited unicode .txt file instead of .csv. For some reason my version of excel doesn't have the option to save in unicode .csv...
Don't quite understand the problem of "rolling my own" parser, but maybe someday someone will take the time to explain it to me better. Still new-ish at this c# stuff...
public void CreateCertificate()
{
File.Create($"
{#"C:\Users\Director\Documents\TestCertApp\TestSub\" + thisYear +
" Certificates- " + certType + "\""}{myFileName}.ppt", 1 ,
FileOptions.None);
}
So I need the backslash between certype and filename to show it belongs within the folder and not next to. It says its an illegal character but how would I get the file in the folder without it?
Based on the code that you wrote the file path that will be generated is (based on my own substitutions for the variables):
String thisYear = "2019";
String certType = "UnderGrad";
String myFileName = "myfile";
String fileToCreate = $"{#"C:\Users\Director\Documents\TestCertApp\TestSub\" + thisYear + " Certificates- " + certType + "\""}{myFileName}.ppt";
Debug.Print(fileToCreate);
Will give you this output:
C:\Users\Director\Documents\TestCertApp\TestSub\2019 Certificates- UnderGrad"myfile.ppt
If you notice there is a " before the filename part of myfile.ppt - This is where the Illegal Character comes from.
If you use this code fragment to generate the path:
String basePath = #"C:\Users\Director\Documents\TestCertApp\TestSub\";
String certificateFolder = $"{thisYear} Certificates- {certType}";
String correctFilePath = Path.Combine(basePath, certificateFolder, $"{myFileName}.ppt");
Debug.Print(correctFilePath);
This will result in the output of:
C:\Users\Director\Documents\TestCertApp\TestSub\2019 Certificates- UnderGrad\myfile.ppt
This version has a \ where the previous code had a " and is no longer illegal, but conforms to the requirement that you wrote the files being in the folder.
Something else to note:
You may want to use Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); to get the path to the MyDocuments folder of the user.
Well, the short answer is that you cannot use an illegal character in a path or file name. Otherwise it wouldn't be illegal. :)
But it seems that the problem here is that you though you were adding a backslash (\) character, when really you were adding a double quote (") character. So if everything else is ok, you can just replace "\"" with "\\" and it should work.
Part of the problem is also that you're doing some strange combination of string interpolation, and it makes the code really hard to read.
Instead you can use just string interpolation to simplify your string (I had to use concatenation below to prevent horizontal scrolling, but you could remove it):
string filePath = $#"C:\Users\Director\Documents\TestCertApp\TestSub\{thisYear} " +
$#"Certificates- {certType}\{myFileName}.ppt";
But even better would be to use the Path.Combine method, along with some variables, to make the intent very clear:
var rootDir = #"C:\Users\Director\Documents\TestCertApp\TestSub"
var fileDir = $"{thisYear} Certificates- {certType}"
var fileName = "{myFileName}.ppt";
var filePath = Path.Combine(rootDir, fileDir, fileName);
what i'm basically trying to do is compare two HUGE text files and if they match write out a string, i have this written but it's extremely slow. I was hoping you guys might have a better idea. In the below example i'm comparing collect[3] splitfound[0]
string[] collectionlist = File.ReadAllLines(#"C:\found.txt");
string[] foundlist = File.ReadAllLines(#"C:\collection_export.txt");
foreach (string found in foundlist)
{
string[] spltifound = found.Split('|');
string matchfound = spltifound[0].Replace(".txt", ""); ;
foreach (string collect in collectionlist)
{
string[] splitcollect = collect.Split('\\');
string matchcollect = splitcollect[3].Replace(".txt", "");
if (matchcollect == matchfound)
{
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
File.AppendAllText(#"C:\copy.txt", "copy \"" + collect + "\" \"C:\\OUT\\" + spltifound[1] + "\\" + spltifound[0] + ".txt\"\n");
break;
}
}
}
Sorry for the vagueness guys,
What I'm trying to do is simply say if content from one file exists in another write out a string(the string isn't important, merely the time to find the two comparatives is). collectionlist is like this:
Apple|Farm
foundlist is like this
C:\cow\horse\turtle.txt
C:\cow\pig\apple.txt
what i'm doing is taking apple from collectionlist, and finding the line that contains apple in foundlist. Then writing out a basic windows copy batch file. Sorry for the confusion.
Answer(All credit to Slaks)
string[] foundlist = File.ReadAllLines(#"C:\found.txt");
var collection = File.ReadLines(#"C:\collection_export.txt")
.ToDictionary(s => s.Split('|')[0].Replace(".txt",""));
using (var writer = new StreamWriter(#"C:\Copy.txt"))
{
foreach (string found in foundlist)
{
string[] splitFound = found.Split('\\');
string matchFound = Path.GetFileNameWithoutExtension(found);
string collectedLine;
if (collection.TryGetValue(matchFound,out collectedLine))
{
string[] collectlinesplit = collectedLine.Split('|');
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + found + "\" \"C:\\O\\" + collectlinesplit[1] + "\\" + collectlinesplit[0] + ".txt\"");
}
}
}
Call File.ReadLines() (.NET 4) instead of ReadAllLines() (.NET 2.0).
ReadAllLines needs to build an array to hold the return value, which can be extremely slow for large files.
If you're not using .Net 4.0, replace it with a StreamReader.
Build a Dictionary<string, string> with the matchCollects (once), then loop through the foundList and check whether the HashSet contains matchFound.
This allows you to replace the O(n) inner loop with an O(1) hash check
Use a StreamWriter instead of calling AppendText
EDIT: Call Path.GetFileNameWithoutExtension and the other Path methods instead of manually manipulating strings.
For example:
var collection = File.ReadLines(#"C:\found.txt")
.ToDictionary(s => s.Split('\\')[3].Replace(".txt", ""));
using (var writer = new StreamWriter(#"C:\Copy.txt")) {
foreach (string found in foundlist) {
string splitFound = found.Split('|');
string matchFound = Path.GetFileNameWithoutExtension(found)
string collectedLine;
if (collection.TryGetValue(matchFound, collectedLine)) {
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + collectedLine + "\" \"C:\\OUT\\"
+ splitFound[1] + "\\" + spltifound[0] + ".txt\"");
}
}
}
First I'd suggest normalizing both files and putting one of them in a set. This allows you to quickly test whether a specific line is present and reduces the complexity from O(n*n) to O(n).
Also you shouldn't open and close the file every time you write a line:
File.AppendAllText(...); // This causes the file to be opened and closed.
Open the output file once at the start of the operation, write lines to it, then close it when all lines have been written.
You have a cartesian product, so it makes sense to index one side instead of doing an enhaustive linear search.
Extract the keys from one file and use either a Set or SortedList data structure to hold them. This will make the lookups much much faster. (Your overall algorithm will be O(N lg N) instead of O(N**2) )
I am new to programming. Is there a way to create multiple .txt files using
data from another file in C#.
like this:
1. we have data.txt with 100 or more strings
string1
string2
string3
...
2. we have textbox1 and textbox2 waiting for user to enter strings
3 . we need to create 100 or more files using strings from data.txt and textboxes strings: name of the fisrt file : string1+textbox1string.txt
and inside it we write:
textbox2string + string1 + textbox1string
the same pattern to create other files, second - string2+textbox1string.txt and inside second - textbox2string + string2 + textbox1string
sorry for my english i am not native speaker.
Well, it sounds like you want something like:
string[] lines = File.ReadAllLines("file1.txt");
foreach (string line in lines)
{
File.WriteAllText(line + textbox1.Text + ".txt",
textbox2.Text + line + textbox1.Text);
}
Basically for very simple tasks like this, the methods in the File class allow "one shot" calls which read or write whole files at a time. For more complicated things you generally have to open a TextReader/TextWriter or a Stream.
If this wasn't what you were after, please provide more information. Likewise if you find the code hard to understand, let us know and we'll try to explain. You may fine it easier with more variables:
string[] lines = File.ReadAllLines("file1.txt");
foreach (string line in lines)
{
string newFile = line + textbox1.Text + ".txt";
string fileContent = textbox2.Text + line + textbox1.Text;
File.WriteAllText(newFile, fileContent);
}
EDIT: If you want to add a directory, you should use Path.Combine:
string newFile = Path.Combine(directory, line + textbox1.Text + ".txt");
(You can do it just with string concatenation, but Path.Combine is a better idea.)
Look into the static File class. It will have a lot of what you want.
http://msdn.microsoft.com/en-us/library/6ka1wd3w.aspx
Sure...
string textbox1string = textbox1.Text, textbox2string = textbox2.Text;
foreach(string line in File.ReadAllLines("data.txt")) {
string path = Path.ChangeExtension(line + textbox1string, "txt");
File.WriteAllText(path, textbox2string + line + textbox1string);
}