I am trying to build a console application using Web Services. Its use 2 functions. The first one GetAllProject outputs ptojectsID and ProjectsNames.
The second function is GetUsersList and it outputs the list of users. Its need as a mandatory parameter the projectID which has been requested by calling the first function.
What I would like to do its to output into a CSV file the projectID, the projectName and the totals of userIDs.
When I run the console, it worked fine but in the column for the totals of userIDs I gets as an output System.String[].
I don't know what I could do to instead of extracting on each line System.String[] the actual total of usersIDs corresponding to each projectID
I don't know how to achieve this. Here you have my code.
string outCsvFile = string.Format(#"C:\\test\\test.csv");
WS.Projects[] pr = db.GetAllProject();
using (StreamWriter file = new StreamWriter(outCsvFile))
{
for (int i = 0; i < pr.Length; ++i)
{
string[] subecjtsIDS = new string[] {""};
subecjtsIDS = db.GetUsersList(pr[i].ProjectID);
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + subecjtsIDS);
}
}
If I'm correctly interpreting your requirements, you're not trying to sum the user IDs (which wouldn't make sense), you're just trying to list them as part of a CSV row. Assuming that's correct...
The problem is that this line
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + subecjtsIDS);
Is attempting to concatenate a string array onto a string. To do this, .NET will call the array's .ToString() method, and, for most reference types in the framework, this just prints the name of the type, i.e. "System.String[]".
Instead, you need to iterate the array and print its contents. The String class provides a nice way to do this: the Join() method:
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + String.Join(",", subecjtsIDS));
If, however, you're trying to add the number of subjects associated with each project to each line, you just want the Length of the array:
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + subecjtsIDS.Length);
Try this
using (StreamWriter file = new StreamWriter(outCsvFile))
{
for (int i = 0; i < pr.Length; ++i)
{
string[] subecjtsIDS = new string[] {""};
subecjtsIDS = db.GetUsersList(pr[i].ProjectID);
foreach(var id in subecjtsIDS)
{
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + id );
}
}
}
This will write more rows but if you use string.Join("," subecjtsIDS) then the number of columns increased and your data will become very complex to understand.
You are going to need to loop through that array and create a string where the values are comma-separated (or whatever it is you want as output). For example:
string outCsvFile = string.Format(#"C:\\test\\test.csv");
WS.Projects[] pr = db.GetAllProject();
using (StreamWriter file = new StreamWriter(outCsvFile))
{
for (int i = 0; i < pr.Length; ++i)
{
string[] subecjtsIDS = new string[] {""};
subecjtsIDS = db.GetUsersList(pr[i].ProjectID);
string formattedSubecjtsIDs;
for (int j = 0; j < subecjtsIDs.length; j++)
{
if (!string.IsNullOrEmpty(formattedSubecjtsIDs))
formattedSubecjtsIDs += ", ";
formattedSubecjtsIDs += subecjtsIDs[j];
}
file.WriteLine(pr[i].ProjectID + ',' + pr[i].ProjectTitle + ',' + formattedSubecjtsIDS);
}
}
Related
My signup page at http://nettpals.in/pages/signup, because, I'm creating an array of user names.
One users has kept his name as john'orielly, which is causing the array to break.
Like this:
var array=['joe','jook','john'orielly'];
Is there any way to escape these ' single quotes?
Code to populate the array:
public static string StringTokenizr(this List<string> list, NpStringTokenizrType type, string splitter = ",")
{
string s = null;
if (list.Count == 0) return null;
for (int i = 0; i < list.Count; i++)
{
if (type == NpStringTokenizrType.IntegerLike)
s += list[i] + splitter;
else s += "'" + list[i] + "'" + splitter;
}
return s.RemoveLast();// removes last comma
}
You can do it this way, assuming the names are stored in a generic list:
var array=[<%=string.Join(", ", arrNames.ConvertAll(name => string.Format("'{0}'", name.Replace("'", "\\'"))))%>];
Saw your edit just now so the above is one liner for the StringTokenizr you have.
You could try replacing the single quote ' with the html equivalent " this would then render on the page correctly and not break your array
I am writing a program which should display the items from an array in a foreach loop.
I wanted to change the elements of the array by adding a string "sad" to each element, but when run the program the array stays the same.
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string[] stringArray = {"hey", "Tom"};
for (int i = 0; i < stringArray.Length; i++ )
{
stringArray[i] += " dad";
Console.WriteLine(stringArray[i]);
}
Array.Resize(ref stringArray, stringArray.Length + 1);
// Add bob to the last element of the array
stringArray[stringArray.Length - 1] =" bob";
foreach (string s in stringArray)
{
string b = s + "sad";
Console.WriteLine(s);
//Console.WriteLine(stringArray);
}
}
}
}
foreach (string s in stringArray)
{
string b = s + "sad";
// ...
}
Here you are creating a new string, completely unrelated to the string in the string-array. You haven't changed the old string (you can't; strings are immutable). You then simply drop this new longer string on the floor - you aren't updating the array etc.
Try instead something like:
for(int i = 0 ; i < stringArray.Length ; i++)
{
stringArray[i] = stringArray[i] + "sad";
}
This replaces every item in the array with a new string. Note that you can't update a list/collection/array etc while iterating with foreach - that can break the iterator. Hence the for loop instead.
Apart from what Chris said, you could simply use LINQ to achieve what you want:
string[] newStringArray = stringArray
.Select(s => s + "sad")
.ToArray();
string b = s + "sad";
Console.WriteLine(s);
//Console.WriteLine(stringArray);
At no point in your code do you alter values in the array. You create a new string from each value in the array, concatenated with the string "sad".
Solution
You can not alter a for-each variable. You'll get a message like:
Cannot assign to 's' because it is a 'foreach iteration variable'.
Instead, settle for a simple for loop.
for(int x = 0; x < stringArray.length; x++)
{
stringArray[x] = stringArray[x] + "sad";
}
Look at this part of the code:
string b = s + "sad";
Console.WriteLine(s);
You are concatenating the string in s with the string "sad", and storing in the variable b. Then you display the content of the variable s. If you would display the content of the variable b isntead, there would be a sad at the end of each string.
I have a text file this is a small part of him its format:
DANNY VIDEO HISTOGRAM DATA
FORMAT VERSION:1.00
SOURCE: <MVI_2483.AVI_Automatic>
DATA:
Frame 000000: 5977,40775,174395,305855,265805
Frame 000001: 5432,21333,456789,123456,111111
Now every line Frame.....Have 256 numbers 5977,40775,174395,305855,265805
In the example i show here only 5 numbers but each line/frame have 256 numbers.
In Form1 i have a List: List Histograms
What i need to do is to read the text file in this case the text file name is Histograms.txt to read the text file and each line/frame with 256 numbers i need to add back to the List.
So the List Histograms will be in the end that in index [0] for example i will have 256 indexes in [0] 5977 in 1 40775 in [2] 174395 in [3] 305955 in [4] 265805 and so on 256 numbers.
Then in index 1 again 256 numbers ...
Then in index [2] and so on...
In the end i should have in the List 3803 index that each index have inside 256 index that each one contain a number.
This is the code of how i am writing the text file when the List is with the numbers and then when i am running the program again i need that it will read and load the text file back to the List. When i am running the program the List is empty.
private void WriteHistograms() // For automatic mode only for now
{
HistogramsFile = new StreamWriter(_outputDir + "\\" + averagesListTextFileDirectory + "\\" + "Histograms.txt", false, Encoding.ASCII);
HistogramsFile.WriteLine("DANNY VIDEO HISTOGRAM DATA\r\nFORMAT VERSION:1.00\r\nSOURCE: " + "<" + averagesListTextFile + ">" + "\r\nDATA: ");
for (int i = 0; i < Histograms.Count; i++)
{
HistogramsFile.Write("Frame " + i.ToString("D6") + ": ");
for (int x = 0; x < Histograms[i].Length; x++ )
{
HistogramsFile.Write(Histograms[i][x] + ",");
}
HistogramsFile.WriteLine("!");
}
HistogramsFile.WriteLine("DATA");
HistogramsFile.Close();
}
Now i have another function: LoadHistograms(), i need to read the text file and add back the numbers to the List.
I added now a photo of the List how it is when writing it to the text file and how the List should looks like after reading it back from the text file.
You can have a fairly good idea how to get it done by using this piece of code.
string line;
List<long[]> list = new List<long[]>();
using (StreamReader file = new StreamReader(#"..\..\Histograms.txt"))
{
do { line = file.ReadLine(); } while (!line.Trim().Equals("DATA:"));
while ((line = file.ReadLine()) != null)
{
long[] valArray = new long[256];
var split = line.Split(new char[] { ':' });
if (split.Length == 2)
{
var valArrayStr = split[1].Split(new char[] { ',' });
for (int i = 0; i < valArrayStr.Length; i++)
{
int result;
if (int.TryParse(valArrayStr[i].Trim(), out result))
valArray[i] = result;
}
}
list.Add(valArray);
}
}
Happy Coding...
I am parsing my data output, however, my data has return charicters in it (\n). So when I run my code, the array is built and one of the arrays (4) is blank data... I have tried using null, "", and " ". Would anyone know how I can prevent that last array from showing?
char[] returnChar= {'\n' };
string parseText = captcha;
string[] words = parseText.Split(returnChar);
int count = words.Length;
for (int i = 0; i < count; i++)
{
if (words[i] == null)
{
MessageBox.Show("This row is empty: " + i);
}
MessageBox.Show(words[i]);
}
When doing String.Split, define the second parameter - StringSplitOptions.
string[] words =
parseText.Split(returnChar, StringSplitOptions.RemoveEmptyEntries);
This way it will skip over empty elements.
I wish to implement a fairly simple CSV checker in my C#/ASP.NET application - my project automatically generates CSV's from GridView's for users, but I want to be able to quickly run through each line and see if they have the same amount of commas, and throw an exception if any differences occur. So far I have this, which does work but there are some issues I'll describe soon:
int? CommaCount = null;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
String Str = null;
//This loops through all the headerrow cells and writes them to the stringbuilder
for (int k = 0; k <= (grd.Columns.Count - 1); k++)
{
sw.Write(grd.HeaderRow.Cells[k].Text + ",");
}
sw.WriteLine(",");
//This loops through all the main rows and writes them to the stringbuilder
for (int i = 0; i <= grd.Rows.Count - 1; i++)
{
StringBuilder RowString = new StringBuilder();
for (int j = 0; j <= grd.Columns.Count - 1; j++)
{
//We'll need to strip meaningless junk such as <br /> and
Str = grd.Rows[i].Cells[j].Text.ToString().Replace("<br />", "");
if (Str == " ")
{
Str = "";
}
Str = "\"" + Str + "\"" + ",";
RowString.Append(Str);
sw.Write(Str);
}
sw.WriteLine();
//The below code block ensures that each row contains the same number of commas, which is crucial
int RowCommaCount = CheckChar(RowString.ToString(), ',');
if (CommaCount == null)
{
CommaCount = RowCommaCount;
}
else
{
if (CommaCount!= RowCommaCount)
{
throw new Exception("CSV generated is corrupt - line " + i + " has " + RowCommaCount + " commas when it should have " + CommaCount);
}
}
}
sw.Close();
And my CheckChar method:
protected static int CheckChar(string Input, char CharToCheck)
{
int Counter = 0;
foreach (char StringChar in Input)
{
if (StringChar == CharToCheck)
{
Counter++;
}
}
return Counter;
}
Now my problem is, if a cell in the grid contains a comma, my check char method will still count these as delimiters so will return an error. As you can see in the code, I wrap all the values in " characters to 'escape' them. How simple would it be to ignore commas in values in my method? I assume I'll need to rewrite the method quite a lot.
var rx = new Regex("^ ( ( \"[^\"]*\" ) | ( (?!$)[^\",] )+ | (?<1>,) )* $", RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
var matches = rx.Matches("Hello,World,How,Are\nYou,Today,This,Is,\"A beautiful, world\",Hi!");
for (int i = 1; i < matches.Count; i++) {
if (matches[i].Groups[1].Captures.Count != matches[i - 1].Groups[1].Captures.Count) {
throw new Exception();
}
}
You could just use a regular expression that matches one item and count the number of matches in your line. An example of such a regex is the following:
var itemsRegex =
new Regex(#"(?<=(^|[\" + separator + #"]))((?<item>[^""\" + separator +
#"\n]*)|(?<item>""([^""]|"""")*""))(?=($|[\" + separator + #"]))");
Just do something like the following (assuming you don't want to have " inside your fields (otherwise these need some extra handling)):
protected static int CheckChar(string Input, char CharToCheck, char fieldDelimiter)
{
int Counter = 0;
bool inValue = false;
foreach (char StringChar in Input)
{
if (StringChar == fieldDelimiter)
inValue = !inValue;
else if (!inValue && StringChar == CharToCheck)
Counter++;
}
return Counter;
}
This will cause inValue to be true while inside fields. E.g. pass '"' as fieldDelimiter to ignore everything between "...". Just note that this won't handle escaped " (like "" or \"). You'd have to add such handling yourself.
Instead of checking the resulting string (the cake) you should check the fields (ingredients) before you concatenate (mix) them. That would give you the change to do something constructive (escaping/replacing) and throwing an exception only as a last resort.
In general, "," are legal in .csv fields, as long as the string fields are quoted. So internal "," should not be a problem, but the quotes may well be.