This code works as it should
foreach (char c in partToDecode)
{
var sum = c - 48;
if (sum > 40)
{
sum = sum - 8;
}
string suma = Convert.ToString(sum, 2).PadLeft(6, '0');
File.AppendAllText(#"C:\Users\jakub\Pulpit\binary.txt", suma);
}
We're inside invisible for i loop (i meant that foreach and this newline is inside of for loop named I) so I need a new line in for loop after foreach loop.
This code isn't working as i wish to, i've got a new line at the beginning and in 2nd line a plain text, the desire is to have a new line after each finish of the foreach loop
string sumaaa = Convert.ToString(sum, 2).PadLeft(6, '0');
File.AppendAllText(#"C:\Users\jakub\Pulpit\binary.txt", sumaaa);
}
FileStream stream = new FileStream(#"C:\Users\jakub\Pulpit\binary.txt", FileMode.Open);
StreamWriter sw = new StreamWriter(stream);
sw.Write("\n");
sw.Close();
}
This is kinda small, after that I have a code for splitting bits to convert small pieces of it to decimal. It worked earlier but i inserted it inside a comment and now it writes nothing. This loop stands alone after all, runs after clicking ok, then i have a form2 which is displayed always, no errors.
for (var k = 0; k < binlines.Count(); k++)
{
var binline = binlines[k];
if (binline != null) //in case it was an empty line error (it's not)
{
string partmessage = binline.Substring(0, 6);
string partdecoded = Convert.ToInt32(partmessage, 2).ToString();
string partmessage2 = binline.Substring(6, 2);
string partdecoded2 = Convert.ToInt32(partmessage2, 2).ToString();
string partmessage3 = binline.Substring(8, 30);
string partdecoded3 = Convert.ToInt32(partmessage3, 2).ToString();
string so on to 15
File.AppendAllText(#"C:\Users\jakub\Pulpit\decimal.txt", partdecoded + "," + partdecoded2 + "," partdecoded3 + "," + partdecoded4...)
}
else
{
}
Now i've got an exception of out of range "index and length must reference to location in string"
I suggest not using a csv format to start with, and write your native binary data to disk. In that case you could just use BinaryReader and BinaryWriter that makes this trivial.
Also it probably worth making some healper methods or a class that can take care of the reading of binary data to int.
Given
public struct BinReader
{
private readonly string _line;
private int _index;
public BinReader(string line)
{
_line = line;
_index = 0;
}
public int GetInt(int length)
{
var result = Convert.ToInt32(_line.Substring(_index, length), 2);
_index += length;
return result;
}
}
Usage
// some test data
var binLines = new List<string>()
{
Convert.ToString(1, 2) + Convert.ToString(2, 2) + Convert.ToString(3, 2) + Convert.ToString(4, 2) + Convert.ToString(5, 2),
Convert.ToString(1, 2) + Convert.ToString(2, 2) + Convert.ToString(3, 2) + Convert.ToString(4, 2) + Convert.ToString(5, 2),
};
// write to file
using (var sw = new BinaryWriter(new FileStream("SomeFileName.dat", FileMode.Create, FileAccess.ReadWrite)))
{
foreach (var reader in binLines.Select(line => new BinReader(line)))
{
sw.Write(reader.GetInt(1));
sw.Write(reader.GetInt(2));
sw.Write(reader.GetInt(2));
sw.Write(reader.GetInt(3));
sw.Write(reader.GetInt(3));
}
}
// read from file
using (var br = new BinaryReader(new FileStream("SomeFileName.dat", FileMode.Open, FileAccess.ReadWrite)))
{
foreach (var reader in binLines.Select(line => new BinReader(line)))
{
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadInt32());
}
}
Proof it works
1
2
3
4
5
1
2
3
4
5
Related
I have file with 1000 random numbers (10 characters long) numbers and i want to create new txt file that will have 10 of these numbers on line and then make a new line with another 10 numbers.
I was only able to either print them all on first line or make a line after every (10) numbers.
{
string path = #"textasd.txt";
string ro = #"nums.dat";
StreamWriter sw = new StreamWriter(path);
StreamReader sr = new StreamReader(ro);
int length = 0,c;
char[] field= new char[10];
while ((c = sr.Read()) != -1)
{
if (char.IsDigit((char)c))
{
pole[length] = (char)c;
length++;
}
else
{
if(length >= 5)
{
sw.WriteLine(field, 0, length);
}
length = 0;
}
}
sr.Close();
sw.Close();
}
Writeline always writes into new line. You need to use Write and have a WriteLine when 10 numbers already written.
{
string path = #"textasd.txt";
string ro = #"nums.dat";
StreamWriter sw = new StreamWriter(path);
StreamReader sr = new StreamReader(ro);
int length = 0,c;
char[] field= new char[10];
var numbersProcessed = 0; //----> this is new
while ((c = sr.Read()) != -1)
{
if (char.IsDigit((char)c))
{
field[length] = (char)c;
length++;
}
else
{
if(length >= 5)
{
//---> new code starts
numbersProcessed++;
sw.Write(field, 0, length);
if (numbersProcessed % 10 == 0)
{
sw.WriteLine();
}
//---> new code ends
}
length = 0;
}
}
sr.Close();
sw.Close();
}
I have a Code in Metatrader that writes some Quotes to CSV, but while doing same in C# the Expert advisor reads the values a different way....
This Code in MetaEditor writes the CSV file:
li_40 = FileOpen(ls_32, FILE_CSV|FILE_WRITE|FILE_SHARE_READ, ";");
if (li_40 > 0) {
FileWrite(li_40, ls_16);
FileClose(li_40);
This Writes in C#:
List<string> listB = new List<string>();
using (StreamReader reader = new StreamReader(File.OpenRead(oFile)))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
listB.Add(reader.ReadLine());
}
reader.Close();
}
using (StreamWriter swOut = new StreamWriter(oFile))
{
foreach (var item in listB)
{
swOut.Write(item);
swOut.Write(Environment.NewLine);
}
for (int i = 0; i <= gridIn.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(", ");
}
value = dr.Cells[i].Value.ToString();
string vals = dr.Cells[2].Value.ToString();
int priceDecimalPlaces = vals.Split('.').Count() > 1
? vals.Split('.').ToList().ElementAt(1).Length
: 0;
string nell = "0";
if (priceDecimalPlaces == 3)
{
nell = "0.001";
}
if (priceDecimalPlaces == 5)
{
nell = "0.00001";
}
if (priceDecimalPlaces == 4)
{
nell = "0.0001";
}
//replace comma's with spaces
value = value.Replace(',', ' ');
//replace embedded newlines with spaces
value = value.Replace(Environment.NewLine, "");
If the difference between the C# double and the Metatrader's current double value is 0.12098-0.12096=2, the Metatrader won't see the value as 2 but something very much higher like 18,17 and so on, but writing this same value from the MetaTrader's code gives correct value...
I read the CSV using _lread:
uchar chBuff[1024];
int res = _lread(hFile, chBuff, 1);
//
//CreateFileA(
res = _lread(hFile, chBuff, 350);
ls_308 = CharArrayToString(chBuff, 0, res, CP_UTF8);
//Alert(Ls_84);
ls_308=StringSubstr(ls_308,0,StringFind(ls_308,"\r\n",0));
if (_lclose(hFile)<0) Print("Error closing");
I think there are some difference between C# doubles on Metatrader and normal Metatrader doubles
The error was caused by the System's encoding language which was different to UTF-8 that was specified in the Metatrader code
ls_308 = CharArrayToString(chBuff, 0, res, CP_UTF8);
So, I changed the UTF to All Code Page assigned by System by doing this
ls_308 = CharArrayToString(chBuff, 0, res, CP_ACP);
Hope someone find this useful..
I have some basic knowledge of C#, but I am having trouble coding something that seems simple in concept. I want to read a file (.asm) containing values such as
#1
#12
#96
#2
#46
etc.
on multiple consecutive lines. I then want to get rid of the # symbols (if they are present), convert the remaining number values to binary, then write these binary values back to a new file (.hack) on their own lines. There isn't a set limit on the number of lines, which is my biggest issue as I don't know how to check for lines dynamically. So far I can only read and convert lines if I code to look for them, then I can't figure out how to write these values on their own lines in the new file. Sorry if this sounds a bit convoluted, but any help would be appreciated. Thanks!
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var line = File.ReadAllText(openFileDialog1.FileName);
using (StreamWriter sw = File.CreateText("testCode.hack"))
{
var str = line;
var charsToRemove = new string[] {"#"};
foreach (var c in charsToRemove)
{
str = str.Replace(c, string.Empty);
}
int value = Convert.ToInt32(str);
string value2 = Convert.ToString(value, 2);
if (value2.Length < 16)
{
int zeroes = 16 - value2.Length;
if(zeroes == 12)
{
sw.WriteLine("000000000000" + value2);
}
}
else
{
sw.WriteLine(value2);
}
}
This code should help you get going real fast:
static void Main(string[] args)
{
string line = string.Empty;
System.IO.StreamReader reader = new System.IO.StreamReader(#"C:\test.txt");
System.IO.StreamWriter writer = new System.IO.StreamWriter(#"C:\test.hack");
while ((line = reader.ReadLine()) != null) // Read until there is nothing more to read
{
if (line.StartsWith("#"))
{
line = line.Remove(0, 1); // Remove '#'
}
int value = -1;
if (Int32.TryParse(line, out value)) // Check if the rest string is an integer
{
// Convert the rest string to its binary representation and write it to the file
writer.WriteLine(intToBinary(value));
}
else
{
// Couldn't convert the string to an integer..
}
}
reader.Close();
writer.Close();
Console.WriteLine("Done!");
Console.Read();
}
//http://www.dotnetperls.com/binary-representation
static string intToBinary(int n)
{
char[] b = new char[32];
int pos = 31;
int i = 0;
while (i < 32)
{
if ((n & (1 << i)) != 0)
{
b[pos] = '1';
}
else
{
b[pos] = '0';
}
pos--;
i++;
}
return new string(b);
}
My suggestion create a List<string>. Here are steps
Read input (.asm) file into List
Open StreamWriter for output (.hack) file.
Loop through List<string> modify the string and write into file.
Code Example:
List<string> lstInput = new List<string>();
using (StreamReader reader = new StreamReader(#"input.asm"))
{
string sLine = string.Empty;
//read one line at a time
while ((sLine = reader.ReadLine()) != null)
{
lstInput.Add(sLine);
}
}
using (StreamWriter writer = new StreamWriter(#"output.hack"))
{
foreach(string sFullLine in lstInput)
{
string sNumber = sFullLine;
//remove leading # sign
if(sFullLine.StartsWith("#"))
sNumber = sFullLine.Substring(1);
int iNumber;
if(int.TryParse(sNumber, out iNumber))
{
writer.WriteLine(IntToBinaryString(iNumber));
}
}
}
public string IntToBinaryString(int number)
{
const int mask = 1;
var binary = string.Empty;
while(number > 0)
{
// Logical AND the number and prepend it to the result string
binary = (number & 1) + binary;
number = number >> 1;
}
return binary;
}
Reference: IntToBinaryString method.
NOTE: Int to Binary String method mentioned in the answer of #TheDutchMan is better choice.
I have a code to read text file and save the data into a double array to plot graph:
string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(#filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var data = line.Split(',');
GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);
lineCount++;
}
ShowGraphData(lineCount);
}
And I have created a public class that initiate the array to [2000,2]:
static class GlobalDataClass
{
public static double[,] dDataArray = new double[2000, 2];
public static long iTotalReadingPoint;
}
My text file will be like:
0,29
1,31
2,32
3,32
4,30
However I want my program to detect the EOF so that the text file can contain random rows and still able to plot the graph not restricted to 2000 rows. Is it possible?please advice.TQ
If you want to use same class then try given code. This is not most optimum memory usage wise but still this should work.
string filename = openFileDialog1.FileName;
var lineCount = 0;
while ((line = reader.ReadLine()) != null)
{
if (GlobalDataClass.dDataArray.GetLength(0) == lineCount)
{
double[,] newTemp = GlobalDataClass.dDataArray;
int increaseLenght = newTemp.Length + 1000;
GlobalDataClass.dDataArray = new double[increaseLenght, 2];
Array.Copy(newTemp, GlobalDataClass.dDataArray, newTemp.LongLength);
}
var data = line.Split(',');
GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);
lineCount++;
}
The StreamReader class has a boolean property named EndOfStream that is essentially EoF for FileStream objects, and there's the Peek() method which is usually the standard way of reading until EoF.
var reader = File.OpenText( ... );
while( reader.Peek() != -1 ) //Peek() returns -1 on EoF or if the stream is not seekable.
{
var line = reader.ReadLine();
...
}
However reading from the file isn't really the problem if you don't want to be restricted to 2,000 lines. You might consider using a generic container of some flavour. For example:
using System.Collections.Generic;
string line = "12,34";
var dDataList = new List<KeyValuePair<double, double>>();
string[] parts = line.Split( ',' );
dDataList.Add( new KeyValuePair<double, double>( Double.Parse( parts[0] ), Double.Parse( parts[1] ) ) );
...
foreach( var pair in dDataList )
Console.WriteLine( "{0} => {1}", pair.Key, pair.Value ); // 12 => 34
Will let you add as many pairs of doubles as you want, within reason, without having to fiddle with array resizing/copying or any of that nasty business. It's generally considered good practice to use a container like List<T> when dealing with an unknown amount of data, and to use arrays when you know exactly how much data you're going to have or the absolute maximum amount of data you can have.
I think you're asking your question a bit wrong; The problem you have is that you are declaring an array of 2000 unit fixed length, but you actually want it to be dynamic length. As Abhinav said, a list may work for you:
firstly, you might consider creating a class/struct for your coordinates:
public class Coordinate
{
public double x;
public double y;
}
Then, create a list of coordinates (of 0 length initially)...
static class GlobalDataClass
{
public static List<Coordinate> dDataArray = new List<Coordinate>();
public static long iTotalReadingPoint;
}
And then add Coordinate objects to your list as you find new lines..
string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(#filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var data = line.Split(',');
Coordinate coord = new Coordinate();
coord.x = double.Parse(data[0]);
coord.y = double.Parse(data[1]);
GlobalDataClass.dDataArray.Add(coord);
lineCount++;
}
ShowGraphData(lineCount);
}
Suppose I have a string with the text: "THIS IS A TEST". How would I split it every n characters? So if n was 10, then it would display:
"THIS IS A "
"TEST"
..you get the idea. The reason is because I want to split a very big line into smaller lines, sort of like word wrap. I think I can use string.Split() for this, but I have no idea how and I'm confused.
Any help would be appreciated.
Let's borrow an implementation from my answer on code review. This inserts a line break every n characters:
public static string SpliceText(string text, int lineLength) {
return Regex.Replace(text, "(.{" + lineLength + "})", "$1" + Environment.NewLine);
}
Edit:
To return an array of strings instead:
public static string[] SpliceText(string text, int lineLength) {
return Regex.Matches(text, ".{1," + lineLength + "}").Cast<Match>().Select(m => m.Value).ToArray();
}
Maybe this can be used to handle efficiently extreme large files :
public IEnumerable<string> GetChunks(this string sourceString, int chunkLength)
{
using(var sr = new StringReader(sourceString))
{
var buffer = new char[chunkLength];
int read;
while((read= sr.Read(buffer, 0, chunkLength)) == chunkLength)
{
yield return new string(buffer, 0, read);
}
}
}
Actually, this works for any TextReader. StreamReader is the most common used TextReader. You can handle very large text files (IIS Log files, SharePoint Log files, etc) without having to load the whole file, but reading it line by line.
You should be able to use a regex for this. Here is an example:
//in this case n = 10 - adjust as needed
List<string> groups = (from Match m in Regex.Matches(str, ".{1,10}")
select m.Value).ToList();
string newString = String.Join(Environment.NewLine, lst.ToArray());
Refer to this question for details:
Splitting a string into chunks of a certain size
Probably not the most optimal way, but without regex:
string test = "my awesome line of text which will be split every n characters";
int nInterval = 10;
string res = String.Concat(test.Select((c, i) => i > 0 && (i % nInterval) == 0 ? c.ToString() + Environment.NewLine : c.ToString()));
Coming back to this after doing a code review, there's another way of doing the same without using Regex
public static IEnumerable<string> SplitText(string text, int length)
{
for (int i = 0; i < text.Length; i += length)
{
yield return text.Substring(i, Math.Min(length, text.Length - i));
}
}
Some code that I just wrote:
string[] SplitByLength(string line, int len, int IsB64=0) {
int i;
if (IsB64 == 1) {
// Only Allow Base64 Line Lengths without '=' padding
int mod64 = (len % 4);
if (mod64 != 0) {
len = len + (4 - mod64);
}
}
int parts = line.Length / len;
int frac = line.Length % len;
int extra = 0;
if (frac != 0) {
extra = 1;
}
string[] oline = new string[parts + extra];
for(i=0; i < parts; i++) {
oline[i] = line.Substring(0, len);
line = line.Substring(len);
}
if (extra == 1) {
oline[i] = line;
}
return oline;
}
string CRSplitByLength(string line, int len, int IsB64 = 0)
{
string[] lines = SplitByLength(line, len, IsB64);
return string.Join(System.Environment.NewLine, lines);
}
string m = "1234567890abcdefghijklmnopqrstuvwxhyz";
string[] r = SplitByLength(m, 6, 0);
foreach (string item in r) {
Console.WriteLine("{0}", item);
}