Prevent last key in string to have a comma - c#

Having trouble figuring out how to prevent the last key in my array to not have a comma. Since its being exported to a .Json file the last key shouldn't have a ",".
I know you can detect it by using .Last();, but I can't seem to make that work. Any recommendations?
//Data Path
string dataPath = #"..\..\FileIOExtraFiles\DataFieldsLayout.txt";
string[] dataList = File.ReadAllLines(dataPath);
//save Data data
using (StreamWriter outStream = new StreamWriter(outputFolder + #"\CharacterStringData3.json"))
{
outStream.WriteLine("{");
for (int i = 0; i < dataFile.Length; i++)
{
string s = dataFile[i];
char last = s.Last();
if (s == "")
{
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \",");
}
else
{
outStream.WriteLine("\"" + dataList[i] + "\"" + " : \"" + s + "\",");
}
}
outStream.WriteLine("}");
}
Output:
{
"data1":"item1",
"data2":item2",
"lastKey":item3",//trying to remove comma from last key in array.
}

As others have pointed out, it doesn't make sense that you are building json manually, but given that this is a question more about technique, here is one approach: you could change it to this:
var commaSuffix = (i == dataFile.Length - 1) ? "," : string.Empty;
outStream.WriteLine("\"" + dataList[i] + "\"" + " : \"" + s + "\"" + commaSuffix);
The suffix would be used on every iteration except the last.

Change this
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \",");
To this
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \""+(i==dataFile.Length?",":""));

Instead of using outStream.WriteLine() at every step, store it in a string. Then you can remove the last comma from that string and write the whole string at once:
//Get last index of comma
int lastCommaIndex = outputString.LastIndexOf(',');
//Create new StringBuilder with everything before the last comma
StringBuilder sb = new StringBuilder(outputString.Substring(0,lastCommaIndex));
//Add everything after the last comma, or just add a closing brace
//sb.Append("}"); //This instead of next line
sb.Append(outputString.Substring(lastCommaIndex+1));
//Add contents of StringBuilder to the Stream
outSteam.WriteLine(sb);

Related

adding first row to to a csv

Having the following function:
string chargeMonth = DateTime.Now.ToString("yyyyMM");
var fileCreationDate = DateTime.Now.ToString("yyyyMMdd");
string fileCreationTime = DateTime.Now.ToString("HHmmss");
string constVal = "MLL";
string fileType = "HIYUV-CHEVRA";
string[] values;
string header, sumRow;
string line, compId;
string inputFile = "records.CSV";
Dictionary<string, System.IO.StreamWriter> outputFiles = new Dictionary<string, System.IO.StreamWriter>();
using (System.IO.StreamReader file = new System.IO.StreamReader("D:\\" + inputFile, Encoding.Default))
{
header = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
values = line.Split(",".ToCharArray());
compId = values[3];
if (!outputFiles.ContainsKey(compId))
{
sumRow = constVal + "-" + fileType + "-" + (String.Format("{0:00000}", Int32.Parse(compId))) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime;
string outputFileName = constVal + "-" + fileType + "-" + (String.Format("{0:00000}", Int32.Parse(compId))) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime + ".CSV";
outputFiles.Add(compId, new System.IO.StreamWriter("D:\\" + outputFileName));
outputFiles[compId].WriteLine(header);
}
outputFiles[compId].WriteLine(line);
}
}
foreach (System.IO.StreamWriter outputFile in outputFiles.Values)
{
outputFile.Close();
}
Which will create csvs based on dictionary's keys/values.
anyways, for each CSV I want to add a row in the FIRST line which is not in a format of the other rows..
somehting like:
line1 aaaabbbbcccc
line2 1 2 3 10 100
line3 2 2 3 10 100
I have no idea how to do that since Im "pulling" data from a dictionary and the line has nothing to do with it. Thanks for any kind of help.
outputFiles[compId].WriteLine(constVal + "-" + fileType + "-" + (String.Format("{0:00000}", Int32.Parse(compId))) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime + ".CSV");
added the following line, it works now. thanks.

Ident Tabs for Multiple New Line String Variable in Net Core

How do I ident a set of lines when writing to a file, with a tabs? I need to go through each line in the variable and create 8 spaces or two tabs for each line, when writing to the new file.
If the string was one line, it would be easy, with " " + test, however this has multiple lines.
public static string testLine=
"Line1" + Environment.NewLine +
"Line2" + Environment.NewLine +
"Line3" + Environment.NewLine +
"Line4" + Environment.NewLine +
using (System.IO.StreamWriter file = new System.IO.StreamWriter(filePath, true))
{
file.WriteLine(testLine);
String is composed of new line, line breaks enters, etc .
Is there any Microsoft Ident function library to support this?
Needs to handle multiple string variables in the future.
All you need to do is prefix the string with whitespace or a tab and replace all occurences off newlines with a newline and a suitable whitespace:
testLine = " " + testLine.Replace( Environment.NewLine, Environment.NewLine + " " );
You can explicitly handle an empty string to avoid indenting nothing:
testLine = String.IsNullOrEmpty(testLine) ? testLine : " " + testLine.Replace( Environment.NewLine, Environment.NewLine + " " );
Substitute "\t" for " " to insert a tab character.

ArgumentOutOfRangeException when I think my code should work

I'm working on a bit of code for school but I keep getting an ArgumentOutOfRangeException
With this code I'm trying to read some data from a .csv file and if it equals the name of the image I want it to remove it from the .csv file whilst keeping the structure intact.
public void checkPair(Image card1, Image card2)
{
this.Image1 = card1;
this.Image2 = card2;
if (Convert.ToString(card1.Source) == Convert.ToString(card2.Source) && (card1 != card2))
{
getPoint(card1, card2);
string path = #"Save1.csv";
var reader = new StreamReader(File.OpenRead(path));
var data = new List<List<string>>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
data.Add(new List<String> { values[0], values[1]
});
}
reader.Close();
string delimiter = ";";
for (int i = 1; i < 5; i++)
{
for (int x = 0; x < 4; x++)
{
if (data[i][x] == Convert.ToString(card1.Source))
{
data[i][x] = null;
}
}
}
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] + Environment.NewLine + data[1][0] + delimiter + data[1][1] + delimiter + data[1][2] + delimiter + data[1][3] + Environment.NewLine + data[2][0] + delimiter + data[2][1] + delimiter + data[2][2] + delimiter + data[2][3] + Environment.NewLine + data[3][0] + delimiter + data[3][1] + delimiter + data[3][2] + delimiter + data[3][3] + Environment.NewLine + data[4][0] + delimiter + data[4][1] + delimiter + data[4][2] + delimiter + data[4][3] + Environment.NewLine + "ready");
I have no idea why I get this error and how to fix it
Initially, I'd change your last line from
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] ....
to something like
var obj1 = data[0][0];
var obj2 = data[0][1];
File.WriteAllText(path, obj1 + delimiter + obj2 .... etc)
If you over inline functions or array accessing, when you get an exception the stack trace won't be that helpful. At least you'll have an idea of the statement that caused the issue.
This technique can prove to be very helpful, if you are looking at an in exception in the logs, after the fact.

Create a QR code from multiple textboxes and decode it back into the textboxes

I have created an application. This app contains the five textboxes id, name, surname, age and score.
When a user clicks the "okay button", these values are stores in an sql database.
Additionally, I want to store all of these information in an QR code. And when I decode it, the information should be shown in the textboxes respectively.
These are the references I am using so far.
using AForge.Video.DirectShow;
using Zen.Barcode;
using ZXing.QrCode;
using ZXing;
I can encode an ID number into a picture box, like so:
CodeQrBarcodeDraw qrcode = BarcodeDrawFactory.CodeQr;
pictureBox1.Image = qrcode.Draw(textBox1.Text, 50);
But I want all of the values in the textboxes to be storee in this QR code.
How can i do that?
The essence of the solution is, that you have to combine all the values from the textboxes into one string. To seperate them after decoding the QR code, you have to add a special character between the data values, that does not exist insinde the user input. After decoding the QR code, you can seperate the values by splitting the string at each occurance of the special character.
This is the quick and dirty way of doing that. If you want the QR code to be conformant to any specific format (like vcard), you have to reserach what it takes to compose the data for this format.
I expect your users cannot enter more than one line into the textboxes, so the newline character can be used as seperator character.
Encode all the information into one QR code.
var qrText = textBox1.Text + "\n" +
textBox2.Text + "\n" +
textBox3.Text + "\n" +
textBox4.Text + "\n" +
textBox5.Text;
pictureBox1.Image = qrcode.Draw(qrText, 50);
You can decode the QR code and assigning the data to the different textboxes again.
var bitmap = new Bitmap(pictureBox1.Image);
var lumianceSsource = new BitmapLuminanceSource(bitmap);
var binBitmap = new BinaryBitmap(new HybridBinarizer(source));
var reader = new MultiFormatReader();
Result result = null;
try
{
result = reader.Decode(binBitmap);
}
catch (Exception err)
{
// Handle the exceptions, in a way that fits to your application.
}
var resultDataArray = result.Text.Split(new char[] {'\n'});
// Only if there were 5 linebreaks to split the result string, it was a valid QR code.
if (resultDataArray.length == 5)
{
textBox1.Text = resultDataArray[0];
textBox2.Text = resultDataArray[1];
textBox3.Text = resultDataArray[2];
textBox4.Text = resultDataArray[3];
textBox5.Text = resultDataArray[4];
}
You can get this done by implementing below code :
"{" + '"' + "name" + '"' + ":" + '"' + txtName.Text + '"' + "," + '"' + "lname" + '"' + ":" + '"' + txtLname.Text + '"' + "," + '"' + "Roll" + '"' + ":" + '"' + txtRoll.Text + '"' + '"' + "class" + '"' + ":" + '"' + txtClass.Text + '"' + "}"
Result will be:
{"name":"Diljit","lname":"Dosanjh","Roll","2071","class":"BCA"}
Such that your QR scanner will recognize the data belong to its specific filed.

C# Regex Issue Getting URLs

To explain briefly, I'm trying to search Google with a keyword, then get the URLs of the top 10 results and save them.
This is the stripped down command line version of the code. It should return 1 result at least. If it works with that, I can apply it to my full version of the code and get all the results.
Basically the code I have right now, it fails if I try to get the entire source of Google. If I include a random section of code from Google's HTML source, it works fine. To me, that means my Regex has an error somewhere.
If there is a better way to do this aside from Regex, please let me know. The URLs are between <h3 class="r"><a href=" and " class=l onmousedown="return clk(this.href
I got this Regex code from a generator, but it's really hard for me to understand Regex, Since nothing I've read explains it clearly. If someone could pick out what's wrong and explain why, I'd greatly appreciate it.
Thanks,
Kevin
using System;
using System.Text.RegularExpressions;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
string keyword = "seo nj";
string html = wc.DownloadString(String.Format("http://www.google.com/search?q={0}", keyword));
string re1 = "(<)"; // Any Single Character 1
string re2 = "(h3)"; // Alphanum 1
string re3 = "(\\s+)"; // White Space 1
string re4 = "(class)"; // Variable Name 1
string re5 = "(=)"; // Any Single Character 2
string re6 = "(\"r\")"; // Double Quote String 1
string re7 = "(>)"; // Any Single Character 3
string re8 = "(<)"; // Any Single Character 4
string re9 = "([a-z])"; // Any Single Word Character (Not Whitespace) 1
string re10 = "(\\s+)"; // White Space 2
string re11 = "((?:[a-z][a-z]+))"; // Word 1
string re12 = "(=)"; // Any Single Character 5
string re13 = ".*?"; // Non-greedy match on filler
string re14 = "((?:http|https)(?::\\/{2}[\\w]+)(?:[\\/|\\.]?)(?:[^\\s\"]*))"; // HTTP URL 1
string re15 = "(\")"; // Any Single Character 6
string re16 = "(\\s+)"; // White Space 3
string re17 = "(class)"; // Word 2
string re18 = "(=)"; // Any Single Character 7
string re19 = "(l)"; // Any Single Character 8
string re20 = "(\\s+)"; // White Space 4
string re21 = "(onmousedown)"; // Word 3
string re22 = "(=)"; // Any Single Character 9
string re23 = "(\")"; // Any Single Character 10
string re24 = "(return)"; // Word 4
string re25 = "(\\s+)"; // White Space 5
string re26 = "(clk)"; // Word 5
Regex r = new Regex(re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9 + re10 + re11 + re12 + re13 + re14 + re15 + re16 + re17 + re18 + re19 + re20 + re21 + re22 + re23 + re24 + re25 + re26, RegexOptions.IgnoreCase | RegexOptions.Singleline);
Match m = r.Match(txt);
if (m.Success)
{
Console.WriteLine("Good");
String c1 = m.Groups[1].ToString();
String alphanum1 = m.Groups[2].ToString();
String ws1 = m.Groups[3].ToString();
String var1 = m.Groups[4].ToString();
String c2 = m.Groups[5].ToString();
String string1 = m.Groups[6].ToString();
String c3 = m.Groups[7].ToString();
String c4 = m.Groups[8].ToString();
String w1 = m.Groups[9].ToString();
String ws2 = m.Groups[10].ToString();
String word1 = m.Groups[11].ToString();
String c5 = m.Groups[12].ToString();
String httpurl1 = m.Groups[13].ToString();
String c6 = m.Groups[14].ToString();
String ws3 = m.Groups[15].ToString();
String word2 = m.Groups[16].ToString();
String c7 = m.Groups[17].ToString();
String c8 = m.Groups[18].ToString();
String ws4 = m.Groups[19].ToString();
String word3 = m.Groups[20].ToString();
String c9 = m.Groups[21].ToString();
String c10 = m.Groups[22].ToString();
String word4 = m.Groups[23].ToString();
String ws5 = m.Groups[24].ToString();
String word5 = m.Groups[25].ToString();
//Console.Write("(" + c1.ToString() + ")" + "(" + alphanum1.ToString() + ")" + "(" + ws1.ToString() + ")" + "(" + var1.ToString() + ")" + "(" + c2.ToString() + ")" + "(" + string1.ToString() + ")" + "(" + c3.ToString() + ")" + "(" + c4.ToString() + ")" + "(" + w1.ToString() + ")" + "(" + ws2.ToString() + ")" + "(" + word1.ToString() + ")" + "(" + c5.ToString() + ")" + "(" + httpurl1.ToString() + ")" + "(" + c6.ToString() + ")" + "(" + ws3.ToString() + ")" + "(" + word2.ToString() + ")" + "(" + c7.ToString() + ")" + "(" + c8.ToString() + ")" + "(" + ws4.ToString() + ")" + "(" + word3.ToString() + ")" + "(" + c9.ToString() + ")" + "(" + c10.ToString() + ")" + "(" + word4.ToString() + ")" + "(" + ws5.ToString() + ")" + "(" + word5.ToString() + ")" + "\n");
Console.WriteLine(httpurl1);
}
else
{
Console.WriteLine("Bad");
}
Console.ReadLine();
}
}
}
You're doing it wrong.
Google has an API for doing searches programmatically. Don't put yourself through the pain of trying to parse HTML with regexes, when there's already a published, supported way to do what you want.
Besides, what you're trying to do -- submit automated searches through Google's Web site and scrape the results -- is a violation of section 5.3 of their Terms of Service:
You specifically agree not to access (or attempt to access) any of the Services through any automated means (including use of scripts or web crawlers)
using RegEx to parse HTML is sado-masochism.
Try using the HTML Agility Pack instead. It will allow you to parse HTML. See this question for an example of using it.

Categories

Resources