IndexOutOfRangeException while adding text to String - c#

My programs adds two arrays into a part of a string using a while loop
ex:
hnames[0] = user
hvals[0] = admin
transformed into: user=admin&
I get IndexOutOfRangeException and i don't know how to fix it.
string[] hnames = names.ToArray(typeof(string)) as string[];
string[] hvals = values.ToArray(typeof(string)) as string[];
String postData = "";
//Loops through the arrays and put data into postData var
while (i < hnames.Length)
{
i++;
int end = hnames.Length;
end--;
if (!(i == end))
{
postData = postData + hnames[i] + "=" + hvals[i] + "&"; //IndexOutOfRangeException here
}
else
{
postData = postData + hnames[i] + "=" + hvals[i];
}
}

You're incrementing i before using it, so at the end of the loop, when i = hnames.Length - 1, the i++; at the start of the loop sets i = hnames.Length, which is over the end of the array. You're also skipping i = 0, in effect.
Move i++; down to the end of the loop.

I just wanted to show you a simplified version of your logic with the foreach as suggested by others. Number of lines may be same but I think this is easy to read.
string[] hnames = names.ToArray(typeof(string)) as string[];
string[] hvals = values.ToArray(typeof(string)) as string[];
string postData = string.Empty;
bool isFirst = true;
int i = 0;
/* Assumption - Both arrays hnames and hvals are of same length.
Otherwise you'll get the same error if hvals.Length < hnames.Length even if you use the foreach
*/
foreach (string hname in hnames)
{
if (isFirst)
{
postData = hname + "=" + hvals[i] + "&"; //IndexOutOfRangeException here
isFirst = false;
}
else
{
postData += hname + "=" + hvals[i];
}
i++;
}

Related

C# if else conditional inside of foreach loop possibly using count

I have working example without the conditional here.
public string RenderPostTags(DMCResultSet resultSet)
{
string output = "";
string filterForm = RenderFilterForm(resultSet);
string pagination = RenderPagination(resultSet);
List<XElement> items = resultSet.items;
foreach(XElement i in items)
{
string tags = "";
if (i.Element("tags") != null)
{
foreach(string tag in i.Element("tags").Elements("tag"))
{
tags += "" + tag + "";
}
}
output += tags;
}
return output;
}
I know just putting a count on it wont work but I've tried several different methods and they haven't worked for me. Could be a syntactical error I'm a total C# noob.
But I need to output adjusted html using a if else conditional similar to this
public string RenderPostTags(DMCResultSet resultSet){
string output = "";
string filterForm = RenderFilterForm(resultSet);
string pagination = RenderPagination(resultSet);
List<XElement> items = resultSet.items;
foreach(XElement i in items){
string tags = "";
if (i.Element("tags") != null) {
int count = 1;
int total = i.Element("tags").Elements("tag").Count;
foreach(string tag in i.Element("tags").Elements("tag")) {
if(count == total){
tags += "" + tag + "";
count++;
}else{
tags += "" + tag +","+ " " + "";
count++;
}
}
}
output += tags;
}
return output;
}
Methods I have tried can be found on this thread.
Foreach loop, determine which is the last iteration of the loop
Thank you for any assitance.
As #Sach said, use the for loop instead of foreach.
string output = "";
List<XElement> items = new List<XElement>();
foreach (XElement i in items)
{
string tags = "";
if (i.Element("tags") != null && i.Element("tags")?.Elements("tag") != null)
{
List<XElement> tagItems = i.Element("tags").Elements("tag").ToList();
if (tagItems == null) continue;
for (int j = 0; j < tagItems.Count(); j++)
{
XElement tag = tagItems[j];
if (j == i.Element("tags")?.Elements("tag").Count() - 1)
{
tags += "" + tag + "";
}
else
{
tags += "" + tag + "," + " " + "";
}
}
}
output += tags;
}
You can write your foreach loop like this to capture both conditions. You can use condition ? true : false to write either/or based on the last item in the collection.
int counter = 1; // Start with 1 since we are using != later on.
int totalRecords = i.Element("tags").Elements("tag").Count();
foreach (string tag in i.Element("tags").Elements("tag"))
tags += "" + tag + counter++ != totalRecords ? ", " : string.Empty + "";
Above is equivalent to
if (i.Element("tags") != null)
{
int counter = 1;
int totalRecords = i.Element("tags").Elements("tag").Count();
foreach (string tag in i.Element("tags").Elements("tag"))
{
if (counter++ == totalRecords)
{
tags += "" + tag + "";
}
else
{
tags += "" + tag + ", " + "";
}
}
}
Make a note that IEnumerable does not have a Count property but have a method Count().
So maybe for namespace reasons the count method would not solve my issue.
However after some toil this solution worked perfectly. Thankyou for those to helped me get to this solution.
public string RenderPostTags(DMCResultSet resultSet){
string output = "";
string filterForm = RenderFilterForm(resultSet);
string pagination = RenderPagination(resultSet);
List<XElement> items = resultSet.items;
foreach(XElement i in items){
string tags = "";
if (i.Element("tags") != null) {
foreach(string tag in i.Element("tags").Elements("tag")){
if(tags != "") tags += ", ";
tags += "" + tag +"";
}
}
output += tags;
}
return output;
}

C# - Unable to remove the back slashes in JSON

I am trying to construct a string which I want to use it to update a JSON.
The code is below
public string ConstructCylicLoop(string fieldName, int LoopCount, string BadDataLabel,string ImmediateParent)
{
string start = "";
string fullbody = "";
string end = "";
string body = "";
for (int i = 0; i < LoopCount; i++)
{
LoopTestData = (new ExcelUtilities().getAPITestData(ApplicationConfiguration.LoopSheetName));
body = "";
foreach (Dictionary<string, string> loopData in LoopTestData)
{
string ParentNode = "";
string Key = "";
string Data = "";
loopData.TryGetValue("ParentNode", out ParentNode);
loopData.TryGetValue("Key", out Key);
loopData.TryGetValue("Data", out Data);
if(ImmediateParent.Equals(ParentNode)) //&& Key.Equals(fieldName)
{
body = body + '"' + Key + '"' + ":" + '"' + Data + '"'+',';
}
}
body = body.Remove(body.Length - 1);
body = "{" + body + "},";
fullbody = fullbody + body;
}
fullbody = fullbody.Remove(fullbody.Length - 1);
return start + fullbody + end;
}
The issue with this code is it always returns a text like this
"{\"my_address_type\":\"primarypropertyaddress\",\"my_address-street\":\"52 Street\",\"my_address-suburb\":\"vinvent\",\"my_address-postcode\":\"2121\"}"
When I update this string to an JSON node, the server is not able to parse it and the issue is with the back slash. Is there a way to remove the back slash. so I get something like this..
"{"my_address_type":"primarypropertyaddress","my_address-street":"52 Street","my_address-suburb":"vinvent","my_address-postcode":"2121"}"
I tried all possibilities but not able to clear/remove the backslash. Any code snippet on removing the backslashes. Thanks in advance.

Union of million line urls in 2 files

File A B contains million urls.
1, go through the url in file A one by one.
2, extract subdomain.com (http://subdomain.com/path/file)
3, if subdomain.com exist file B, save it to file C.
Any quickest way to get file C with c#?
Thanks.
when i use readline, it have no much different.
// stat
DateTime start = DateTime.Now;
int totalcount = 0;
int n1;
if (!int.TryParse(num1.Text, out n1))
n1 = 0;
// memory
dZLinklist = new Dictionary<string, string>();
// read file
string fileName = openFileDialog1.FileName; // get file name
textBox1.Text = fileName;
StreamReader sr = new StreamReader(textBox1.Text);
string fullfile = File.ReadAllText(#textBox1.Text);
string[] sArray = fullfile.Split( '\n');
//IEnumerable<string> sArray = tool.GetSplit(fullfile, '\n');
//string sLine = "";
//while (sLine != null)
foreach ( string sLine in sArray)
{
totalcount++;
//sLine = sr.ReadLine();
if (sLine != null)
{
//string reg = "http[s]*://.*?/";
//Regex R = new Regex(reg, RegexOptions.Compiled);
//Match m = R.Match(sLine);
//if(m.Success)
int length = sLine.IndexOf(' ', n1); // default http://
if(length > 0)
{
//string urls = sLine.Substring(0, length);
dZLinklist[sLine.Substring(0,length)] = sLine;
}
}
}
TimeSpan time = DateTime.Now - start;
int count = dZLinklist.Count;
double sec = Math.Round(time.TotalSeconds,2);
label1.Text = "(" + totalcount + ")" + count.ToString() + " / " + sec + " = " + (Math.Round(count / sec,2)).ToString();
sr.Close();
I would go for using Microsoft LogParser for processing big files: MS LogParser. Are you limited to implement it in described way only?

using .replace to replace a word in text document (c#)

currently have the following code:
string[] fileLineString = File.ReadAllLines(Server.MapPath("~") + "/App_Data/Users.txt");
for (int i = 0; i < fileLineString.Length; i++)
{
string[] userPasswordPair = fileLineString[i].Split(' ');
if (Session["user"].ToString() == userPasswordPair[0])
{
userPasswordPair[i].Replace(userPasswordPair[1], newPasswordTextBox.Text);
}
}
}
the text file is set out as: 'username' 'password
what i'm trying to do is be able to edit the password and replace it with a new one using my code, but my code seems to do nothing and the text file just stays the same.
string[] fileLineString = File.ReadAllLines(Server.MapPath("~") + "/App_Data/Users.txt");
for (int i = 0; i < fileLineString.Length; i++)
{
string[] userPasswordPair = fileLineString[i].Split(' ');
if (Session["user"].ToString() == userPasswordPair[0])
{
// set the new password in the same list and save the file
fileLineString[i] = Session["user"].ToString() + " " + newPasswordTextBox.Text;
File.WriteAllLines((Server.MapPath("~") + "/App_Data/Users.txt"), fileLineString);
break; // exit from the for loop
}
}
At the moment, you're not storing the file.
Your replace is not assigned to a variable (Replace does not edit or write anything, it just returns the new string object).
Corrected code:
string[] fileLineString = File.ReadAllLines(Server.MapPath("~") + "/App_Data/Users.txt");
for (int i = 0; i < fileLineString.Length; i++)
{
string[] userPasswordPair = fileLineString[i].Split(' ');
if (Session["user"].ToString() == userPasswordPair[0])
{
fileLineString[i] = fileLineString[i].Replace(userPasswordPair[1], newPasswordTextBox.Text);
break;
}
}
File.WriteAllLines((Server.MapPath("~") + "/App_Data/Users.txt", fileLineString);
String _userName = "User";
String _newPassword = "Password";
// Reading All line from file
String _fileContent = System.IO.File.ReadAllLines("filePath").ToString();
// Pattern which user password like to changed
string _regPettern = String.Format(#"{0} ?(?<pwd>\w+)[\s\S]*?", _userName);
Regex _regex2 = new Regex(_regPettern, RegexOptions.IgnoreCase);
String _outPut = Regex.Replace(_fileContent, _regPettern, m => m.Groups[1] + " " + _newPassword);
// Writing to file file
System.IO.File.WriteAllText("filePath", _outPut);

Can only display array by iterating through a for loop

Hello I am trying to make a C# program that downloads files but I am having trouble with the array.
I have it split up the text for downloading and put it into a 2 level jagged array (string[][]).
Now I split up the rows up text by the | char so each line will be formatted like so:
{filename}|{filedescription}|{filehttppath}|{previewimagepath}|{length}|{source}
when I use short test text to put it into a text box it displays fine in the text box.
IE: a string like test|test|test|test|test|test
but if I put in a real string that I would actually be using for the program to DL files the only way I get the string to display is to iterate through it with a for or foreach loop. If I try to access the data with the index I get an index missing error. (IE array[0])
So this is the code that gets the array to display:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
}
And then this is the code that gives an index missing error:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
textBox1.Text = textBox1.Text + i[0] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[1] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[2] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[3] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[4] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[5] + Environment.NewLine;
}
}
Any help is this is apreciated I don't see why I can access they data through a for loop but not directly it just doesn't make any sense to me.
Also, here is the code that generates the array:
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i<FinalArray.Length;i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}
In your first example you are using the actual length of each inner array to do the concatenation. In your second example you are hard coded to the same length yet you said in the intro it was a jagged array.
Can you show what your input text looks like?
you are not doing the same concatenation in first and second example so the resulting stings are very different.
first = "\r\n Crazy Video\r\n\\\\newline\r\nThis Video is absolutly crazy!\r\n\\\\newline\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\n\\\\newline\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n\\\\newline\r\n300\r\n\\\\newline\r\nhtt://fakeurl.fake \r\n\\\\newline\r\n"
second = "\r\n Crazy Video\r\nThis Video is absolutly crazy!\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n300\r\nhtt://fakeurl.fake \r\n"
using System;
using NUnit.Framework;
namespace ClassLibrary5
{
public class Class1
{
[Test]
public void test()
{
var temp = new[]
{
" Crazy Video|This Video is absolutly crazy!|htt://fakeurl.fake/vidfolder/video.flv|htt://fakeurl.fake/imgfolder/img.j‌​pg|300|htt://fakeurl.fake "
};
var final = finalList(temp);
var first = Form1(final, "path");
var second = Form2(final, "path");
Assert.IsTrue(first.CompareTo(second) == 0);
}
public string Form1(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
for (int j = 0; j < i.Length; j++)
{
textString = textString + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
return textString;
}
public string Form2(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
textString = textString + i[0] + Environment.NewLine;
textString = textString + i[1] + Environment.NewLine;
textString = textString + i[2] + Environment.NewLine;
textString = textString + i[3] + Environment.NewLine;
textString = textString + i[4] + Environment.NewLine;
textString = textString + i[5] + Environment.NewLine;
}
return textString;
}
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i < FinalArray.Length; i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}
}
}
Are you sure each String[] in string[][] textList has 6 elements?
Try to replace:
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
with:
for(int j=0;j<6;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
And see if you get the same result. Your middle one has different logic than your first one. To troubleshoot, first make the logic the same, and then continue troubleshooting from there.

Categories

Resources