I'm reading in a text file using BinaryReader, then doing what I want with it (stripping characters, etc..), then writing it out using BinaryWriter.
Nice and simple.
One of the things I need to do before I strip anything is to:
Check that the amount of characters in the file is even (obviously file.Length % 2) and
If the length is even, check that every preceding character is a zero.
For example:
0, 10, 0, 20, 0, 30, 0, 40.
I need to verify that every second character is a zero.
Any ideas? Some sort of clever for loop?
OKAY!
I need to be a lot more clear about what I'm doing. I have file.txt that contains 'records'. Let's just say it's a comma delimited file. Now, What my program needs to do is read through this file, byte by byte, and strip all of the characters we don't want. I have done that. But, some of the files that will be going through this program will be single byte, and some will be double byte. I need to deal with both of these possibilities. But, I need to figure out whether the file is single or double byte in the first place.
Now, obviously if the file is double byte:
The file length will be divisible by 2 and
Every preceding character will be a zero.
and THAT'S why I need to do this.
I hope this clears some stuff up..
UPDATE!
I'm just going to have a boolean in the arguments - is16Bit. Thanks for your help guys! I would have rather deleted the question but it won't let me..
Something like this in a static class:
public static IEnumerable<T> EveryOther(this IEnumerable<T> list)
{
bool send = true;
foreach(var item in list)
{
if (send) yield return item;
send = !send;
}
}
and then (using the namespace of the previous class)
bool everyOtherIsZero = theBytes.EveryOther().All(c => c == 0);
string[] foo = file.text.Split(new{','}, StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<foo .Length; i+=2)
{
if(file[i]!="0")
return false;
}
How about this
string content = File.ReadAllText(#"c:\test.txt");
if (content.Length % 2 != 0)
throw new Exception("not even");
for(int i = 0; i < content.Length; i+=2)
if (content[i] != '0')
throw new Exception("no zero found");
Related
I have a problem my code is not efficient enough. He thinks he knows the content. How do I write the code so it can work with any file. So he practically only excludes numbers and ignores the words (strings).
public static int SumUpFileContent(string file)
{
int sum = 0;
var lines = File.ReadAllLines(file);
foreach (var line in lines)
{
if (int.TryParse(line, out int i))
sum += i;
}
return sum;
}
Keep in mind :
This doesn't work with numbers that have decimals, only integers. replace int.TryParse() with double.TryParse() if you have to.
The data must come in a very specific format (i.e. every entry must be on its own line)
From the information you provided you could split the file content in to an array
then for each item in the array use an int.tryParse to see if it is a number. (this is assumed that the numbers are always int)
I hope and you can help me please, I have a label that shows a value in binary.
Example: "1000010101", this data, I'm reading it with an inverted for. That is, starting from right to left, the binary number is dynamic, so it will not always be the same.
Until now this is my idea, but it does not give me any value
for (int i = lbl_conversion.Text.Length; i > 0; i--)
{
if (st[i] == 1)
{
MessageBox("1");
}
else
{
MessageBox("0");
}
}
What I would like is to read character by character from left to right and know if it is "1" or "0" and then make a comparison, could someone support me to get that result?
Thank you.
Since strings are zero based, correct for loop will be
// Note "- 1" and ">="
for (int i = lbl_conversion.Text.Length - 1; i >= 0; --i)
if (st[i] == '1') //DONE: comparing with character, not integer
{
MessageBox("1");
}
else
{
MessageBox("0");
}
Or you can just Reverse the string (with a help of Linq):
// Let's read each character in reversed order
foreach (char c in lbl_conversion.Text.Reverse())
MessageBox(c.ToString());
just one more (similar to prev posted)
string s="10111011";
s.Reverse().ToList().ForEach(ch=>Console.WriteLine(ch=='1'?"A":"0"));
When you need read the string to right to left, typically you know the number of character to have to read.
I have this function.
private string GetValue(string strValor, int lenght)
{
if (strValor.Length > lenght)
return strValor.Substring(strValor.Length - lenght, lenght);
return strValor;
}
strValor: String to read.
lenght: Number of character to read.
Example: GetValue("R6C5736423792", 10); return "5736423792"
I need to know is there some string at exact location on the .txt file.
I know how to found concrete string with Contains method, but since I do not need to search whole file (string will always be on the same location) I'm trying to find quickest solution.
if (searchedText.Contains(item))
{
Console.WriteLine("Found {0}",item);
break;
}
Thanks
If it's in UTF-8 and isn't guaranteed to be ASCII, then you'll just have to read the relevant number of characters. Something like:
using (var reader = File.OpenText("test.txt"))
{
char[] buffer = new char[16 * 1024];
int charsLeft = location;
while (charsLeft > 0)
{
int charsRead = reader.Read(buffer, 0, Math.Min(buffer.Length,
charsLeft));
if (charsRead <= 0)
{
throw new IOException("Incomplete data"); // Or whatever
}
charsLeft -= charsRead;
}
string line = reader.ReadLine();
bool found = line.StartsWith(targetText);
...
}
Notes:
This is inefficient in terms of reading the complete line starting from the target location. That's simpler than looping to make sure the right data is read, but if you have files with really long lines, you may want to tweak this.
This code doesn't cope with characters which aren't in the BMP (Basic Multilingual Plane). It would count them as two characters, as they're read as two UTF-16 code units. This is unlikely to affect you.
if(searchedText.SubString(i, l).Contains(item))
where i is the starting index and l is the length of the string you're searching for.
Since you're using Contains, you have some margin in l.
So, what I'm trying to do this something like this: (example)
a,b,c,d.. etc. aa,ab,ac.. etc. ba,bb,bc, etc.
So, this can essentially be explained as generally increasing and just printing all possible variations, starting at a. So far, I've been able to do it with one letter, starting out like this:
for (int i = 97; i <= 122; i++)
{
item = (char)i
}
But, I'm unable to eventually add the second letter, third letter, and so forth. Is anyone able to provide input? Thanks.
Since there hasn't been a solution so far that would literally "increment a string", here is one that does:
static string Increment(string s) {
if (s.All(c => c == 'z')) {
return new string('a', s.Length + 1);
}
var res = s.ToCharArray();
var pos = res.Length - 1;
do {
if (res[pos] != 'z') {
res[pos]++;
break;
}
res[pos--] = 'a';
} while (true);
return new string(res);
}
The idea is simple: pretend that letters are your digits, and do an increment the way they teach in an elementary school. Start from the rightmost "digit", and increment it. If you hit a nine (which is 'z' in our system), move on to the prior digit; otherwise, you are done incrementing.
The obvious special case is when the "number" is composed entirely of nines. This is when your "counter" needs to roll to the next size up, and add a "digit". This special condition is checked at the beginning of the method: if the string is composed of N letters 'z', a string of N+1 letter 'a's is returned.
Here is a link to a quick demonstration of this code on ideone.
Each iteration of Your for loop is completely
overwriting what is in "item" - the for loop is just assigning one character "i" at a time
If item is a String, Use something like this:
item = "";
for (int i = 97; i <= 122; i++)
{
item += (char)i;
}
something to the affect of
public string IncrementString(string value)
{
if (string.IsNullOrEmpty(value)) return "a";
var chars = value.ToArray();
var last = chars.Last();
if(char.ToByte() == 122)
return value + "a";
return value.SubString(0, value.Length) + (char)(char.ToByte()+1);
}
you'll probably need to convert the char to a byte. That can be encapsulated in an extension method like static int ToByte(this char);
StringBuilder is a better choice when building large amounts of strings. so you may want to consider using that instead of string concatenation.
Another way to look at this is that you want to count in base 26. The computer is very good at counting and since it always has to convert from base 2 (binary), which is the way it stores values, to base 10 (decimal--the number system you and I generally think in), converting to different number bases is also very easy.
There's a general base converter here https://stackoverflow.com/a/3265796/351385 which converts an array of bytes to an arbitrary base. Once you have a good understanding of number bases and can understand that code, it's a simple matter to create a base 26 counter that counts in binary, but converts to base 26 for display.
I am attempting to take numbers (characters 0-9) in from a file and store them in memory.
Lets say we have a string called "register" (and can only (must) hold 5 chars max) and the register string will take in numbers that are read from the file so for example:
File1.txt:
The house number is 10 and the price is 4000 and 3.
So the register would be filled with the following: "10400"
Some logic would then be performed against the string and then the first char would be removed from string and everything would shift 1 to the left and another char (number) from the file would be added e.g.:
04000
and then...
40003
Hopefully somebody could shed some light on this and provide some ways of achieving this :)
Well, if you want to lop the first character off a string and add on one at the end, you can just say:
string s = "10400";
string t = s.Substring(1) + "0";
This gives t = "04000". Repeating:
string u = t.Substring(1) + "3";
This gives u = "40003".
So, what more do you want? Figuring out the logic of what to add to the end is your job.
OK...
First, a FileStream and associated StreamReaders will allow you to read from the file in pretty much any format you desire. This will be important because your specific algorithm will determine the retrieval method.
Boiling it down, you want to read characters from the file, and when that character is a number, store it in the register, continuing in this manner until you have five number characters in the register. Then, you'll do some logic that results in the first number no longer being useful, so you truncate it and get the next value.
How about something along these lines?
var register = new StringBuilder();
using(var stream = File.Open("File1.txt"))
{
bool ended, fileEnded;
int buffer;
while(!ended)
{
while(register.Length < 5 && !fileEnded)
{
buffer = stream.ReadByte();
if(buffer == -1)
{
fileEnded = true;
break;
}
var myChar = (char)buffer;
if(Char.IsNumber(myChar))
StringBuilder.Append(myChar);
}
//at this point you have 5 characters in register (or have run out of file).
//perform your logic, then remove the front character
register.Remove(0,1);
//repeat the loop. You won't get any more new characters once you reach the end of file,
//but the main loop will keep running until you set ended to true
if(WereDone())
ended=true;
}
stream.Close();
}
You could also read the entire file into a string variable, then apply a Regex that will find number characters, concatenate those into a large buffer, then fill your Register from that. That is a better approach for a small file, but this one will work for any file size.
You can create an extension method to List like so:
static class Helper
{
public static void Push<T>(this List<T> list, T item)
{
if (list.Count == 5)
list.RemoveAt(0);
list.Add(item);
}
}
And then you can use it like:
List<char> queue = new List<char>(5);
queue.Push('1');
queue.Push('0');
queue.Push('4');
queue.Push('0');
queue.Push('0');
Subsequent Call to Push will remove the first char and add the last
queue.Push('1');
I would likely put a method for fetching the correct string into a value. See below for an example:
static string FetchRegister(string Source, int Max, int StartIndex)
{
string Register = string.Empty;
int RegisterIndex = 0;
for (int i = 0; i < Source.Length; i++)
{
if (char.IsNumber(Source[i]))
{
if (RegisterIndex >= StartIndex)
{
Register += Source[i].ToString();
if (Register.Length == Max)
{
return Register;
}
}
RegisterIndex += 1;
}
}
return Register;
}