so basically i'm developing a networking program in c# and I'm trying to send a string from the server to the client using stream reader but I'm having a very strange issue. When I use this code...
[Server Side]
foreach (DataRow row in StocksTable.Rows)
{
stocks += row["description"] + "," + row["buy"] + "," + row["sell"] + ",";
}
[Client]
textBox3.Text = streamReader.ReadLine();
... it works but it only returns the first row. When I change the "\n" with ";" for example so that everything is on one row, the client crashes.
I tried using an iterator to print all the rows but it doesn't work as well.
I know it sounds funny and probably there's some simple explanation but I've been stuck on this for a while and i'm getting confused.
EDIT:
I tried iterating and this thing works:
for (int i = 0; i < 5; i++)
{
textBox3.Text += streamReader.ReadLine();
}
(5 is the number of rows in the string)
but this doesn't:
while (true)
{
string s = streamReader.ReadLine();
if (s != null)
{
textBox3.Text += s;
}
else
{
break;
}
}
I'm going to assume that stocks is a string. A string can contain many lines (lines defined as string delimited by a CR, LF, or CRLF). In this case it appears you are creating multiple lines in the string by using \n. There for:
textBox3.Text = streamReader.ReadLine();
Will read the first Line in the stream.
You should use the StreamReader.ReadToEnd() in order to read all the lines. ReadNextLine will only read a line and stop at a \n character.
If you iterate, you should check if more content is still available.
Related
My code searches through a list and then if it finds a match, it displays the object in my listbox. My problem is that if there is more than 1 object in the list (if im searching for Alex and there is two objects with the name Alex), it returns it all on the same line instead of separating them to separate lines.
I coulda swore match += request + "\n"; was how to do it correctly, but it's not working.
Edit: One thing I dont understand is that if i just have match += request; it will allow me to use the horizontal scroll bar on my listbox to see everything written. And if i use match += request + "\n"; or match += request + Environment.NewLine; it doesn't let me use the scroll box and just cuts off.
public string SearchRequest(string keyword)
{
bool found = false;
string noMatch = "No requests with the name " + "'" + keyword + "'" + " were found";
string match = "";
foreach (ServiceRequest request in Requests)
{
if (request.searchKeywords(keyword))
{
match += request + "\n";
found = true;
}
}
if (found)
return match;
else
return noMatch;
}
/
public bool searchKeywords(string keyword)
{
if (keyword == name)
return true;
else
return false;
}
/
private void btnSearch_Click(object sender, EventArgs e)
{
lstSearch.Items.Clear();
lstSearch.Items.Add(myRequest.SearchRequest(txtSearch.Text));
}
Try
match += request + Environment.NewLine;
If you put all the results in a single string then it will still be a single item in the list.
Return an array of strings from the method instead of a single string:
public string[] SearchRequest(string keyword) {
List<string> match = new List<string>();
foreach (ServiceRequest request in Requests) {
if (request.searchKeywords(keyword)) {
match.Add(request.ToString());
}
}
if (match.Count > 0) {
return match.ToArray();
} else {
return new string[] { "No requests with the name " + "'" + keyword + "'" + " were found" };
}
}
Then use AddRange to add the strings as separate items in the list:
lstSearch.Items.AddRange(myRequest.SearchRequest(txtSearch.Text));
In Windows OS, the new line is two characters, the Carriage Return \r followed by Line Feed: \n. You can use Environment.NewLine as a shortcut (preferred) or append "\r\n" yourself. See further wikipedia entry on newline
Use one of these:
match += request + "\r\n";
Use an string literal:
match += request + #"
";
OR only at runtime will this resolve:
match += request + System.Environment.NewLine;
On Unix "\n"
You can't add a string with newlines to a listbox and expect it to show up as multiple items. Either split the string on newline and add each line separately to the listbox, or return a list of strings from your search function to begin with, avoiding the need for a split afterwards.
Struggling with a C# Component. What I am trying to do is take a column that is ntext in my input source which is delimited with pipes, and then write the array to a text file. When I run my component my output looks like this:
DealerID,StockNumber,Option
161552,P1427,Microsoft.SqlServer.Dts.Pipeline.BlobColumn
Ive been working with the GetBlobData method and im struggling with it. Any help with be greatly appreciated! Here is the full script:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string vehicleoptionsdelimited = Row.Options.ToString();
//string OptionBlob = Row.Options.GetBlobData(int ;
//string vehicleoptionsdelimited = System.Text.Encoding.GetEncoding(Row.Options.ColumnInfo.CodePage).GetChars(OptionBlob);
string[] option = vehicleoptionsdelimited.Split('|');
string path = #"C:\Users\User\Desktop\Local_DS_CSVs\";
string[] headerline =
{
"DealerID" + "," + "StockNumber" + "," + "Option"
};
System.IO.File.WriteAllLines(path + "OptionInput.txt", headerline);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + "OptionInput.txt", true))
{
foreach (string s in option)
{
file.WriteLine(Row.DealerID.ToString() + "," + Row.StockNumber.ToString() + "," + s);
}
}
Try using
BlobToString(Row.Options)
using this function:
private string BlobToString(BlobColumn blob)
{
string result = "";
try
{
if (blob != null)
{
result = System.Text.Encoding.Unicode.GetString(blob.GetBlobData(0, Convert.ToInt32(blob.Length)));
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
Adapted from:
http://mscrmtech.com/201001257/converting-microsoftsqlserverdtspipelineblobcolumn-to-string-in-ssis-using-c
Another very easy solution to this problem, because it is a total PITA, is to route the error output to a derived column component and cast your blob data to a to a STR or WSTR as a new column.
Route the output of that to your script component and the data will come in as an additional column on the pipeline ready for you to parse.
This will probably only work if your data is less than 8000 characters long.
I'd appreciate if someone could advise on the following.
I read the file containing the below text and writing each line into the List<string>:
CODE/1
NAME/some_name1
SHORT_NAME/short_name1
CODE/2
NAME/document is a piece of paper
containing information often
used as proof of something
SHORT_NAME/document is a piece
Now I'm parsing the list to get CODE, NAME and SHORT_NAME separately.
The problem is that some lines containing NAME have one sencence which is broken into several lines due to its long length. I want to append these lines into one sentence, the output should be:
...
NAME/document is a piece of paper containing information often used as proof of something
...
My code appends only one next line:
List<string> lines = File.ReadLines(path).ToList();
List<string> full_lines = new List<string>();
foreach (string line in lines)
{
if (line.StartsWith("NAME"))
{
name_index = lines.IndexOf(line);
string new_line = "";
if (!lines.ElementAt(name_index + 1).StartsWith("SHORT_NAME")) //checking if
//the next line does not start with SHORT_NAME (then it is continuation of NAME)
{
new_line = line + " " + lines.ElementAt(name_index + 1);//appending the next
//line
full_lines.Add(new_line); //adding into new list
}
else
{
full_lines.Add(line);
}
}
}
So the output is:
...
NAME/document is a piece of paper
...
So, how can I append all lines?
Thank you
When you're reading the file, read each line separately, instead of all them together. Then don't create a new line unless it starts with a key word or if the '/' is unique unless the line contains a '/'. Something like this might help:
List<string> full_lines = new List<string>();
System.IO.StreamReader sr = new System.IO.StreamReader(path);
string line = "";
while(!sr.EndOfStream)
{
line = sr.ReadLine();
if(!line.Contains("/"))
{
full_lines[full_lines.Count - 1] += line;
}
else
full_lines.Add(line);
}
change
if (!lines.ElementAt(name_index + 1).StartsWith("SHORT_NAME")) //checking if
//the next line does not start with SHORT_NAME (then it is continuation of NAME)
{
new_line = line + " " + lines.ElementAt(name_index + 1);//appending the next
//line
full_lines.Add(new_line); //adding into new list
}
else
{
full_lines.Add(line);
}
to
new_line = line;
name_index++;
while (!lines.ElementAt(name_index).StartsWith("SHORT_NAME"))
{
new_line = new_line + " " + lines.ElementAt(name_index);//appending the next line
name_index++;
}
full_lines.Add(new_line);
I want to write a string next to a line, randomly could be any line, also I want to know how to delete a line from it, here is how my StreamReader works:
using (StreamReader sb = new StreamReader("admin.txt"))
{
string[] ffoo = File.ReadAllLines("admin.txt");
string[] ppoof = ffoo[0].Split(';');
string line;
while ((line = sb.ReadLine()) != null)
{
if (line.StartsWith("#" + Server.Name.ToLower() + ": "))
{
string[] punch = line.Split(';');
if (!punch.Contains(Channel.Name.ToLower()))
{
StringBuilder str = new StringBuilder("admin.txt");
str.Append(Channel.Name.ToLower() + ";");
return;
}
}
}
Here is how the list is made:
#main: alien;nobody;somebody;
#devs: headdev;wae;
It reads it fine just it can't write something next to main channel, I mean I can only write a line or a string next to end of it which is on dev, and I want to write something on main, also I have some problems on how to delete an admin from main or dev. also this file would be oversize, maybe includes 500 lines at all after we use it, so please if you can give a solution for big files, thanks!
When calling StringBuilder.Append it appends to the end of the string.
When calling the StringBuilder(string) constructor it will append to the string passed as parameter for the constructor.
In this case you are passing "Admin.txt" as a string, but you really want to pass the content of Admin.txt, so you need to read the content of it.
This should do the trick:
string[] lines = File.ReadAllLines("admin.txt");
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith(string.Format("#{0}: ", Server.Name.ToLower()))
{
if (!lines[i].Split(';').Contains(Channel.Name.ToLower()))
lines[i] += ";" + Channel.Name.ToLower();
}
}
File.WriteAllLines("admin.txt", lines);
I'm sorry if I misunderstood what you wanted to do though.
I'm getting content from a database and returning it for Ajax processing via Javascript. Pretty simple stuff. The issue here is that I can't seem to find a good way to loop through the data and the MSDN documentation is obscenely poor for its odbcreader methods.
using (OdbcCommand com = new OdbcCommand("SELECT * FROM pie_data WHERE Pie_ID = ?",
con)) {
if (Request.Form["reference_id"] == "") {
returnError();
} else {
com.Parameters.AddWithValue("", Request.Form["reference_id"]);
com.ExecuteNonQuery();
using (OdbcDataReader reader = com.ExecuteReader()) {
string finalstring = "";
while (reader.Read()) {
if(reader.HasRows) {
finalstring = reader.GetString(9) + ",";
for (int i = 0; i <= 8; i = i + 1) {
finalstring = finalstring + reader.GetValue(i).ToString() + ",";
}
finalstring = finalstring + "|";
reader.NextResult();
}
}
if (finalstring != "") {
finalstring = finalstring.Remove(finalstring.Length -1, 1);
Response.Write(finalstring);
}
}
noredirect = 1;
}
}
However, here is the sample output:
00001,0,Pie Johnson,piesaregreat#yum.com,,,10/7/2010 12:00:00 AM,Bakery,N/A,N/A,
As you can see, the second deliminator is not appearing at all, when it really should. Also, this query, when run in heidisql, returns a good number of rows, not just this one result. Once I have it passed to the Javascript, I can figure it out since I have much more experience with that and I've actually done this before via PHP.
I would use a DataTable and a DataAdapter:
String finalString;
var tblPieData = new DataTable();
using(var con = new OdbcConnection(connectionString))
using (OdbcDataAdapter da = new OdbcDataAdapter("SELECT * FROM pie_data WHERE Pie_ID = ?", con))
{
da.SelectCommand.Parameters.AddWithValue("Pie_ID", reference_id);
da.Fill(tblPieData);
var rowFields = tblPieData.AsEnumerable()
.Select(r => string.Join(",", r.ItemArray));
finalString = string.Join("|", rowFields);
}
You are replacing the value of finalstring in every iteration of the loop. This will cause only the values for a single row to be returned:
finalstring = reader.GetString(9) + ",";
as well as removing the last character at the end of each iteration through the columns in the rows (the pipe, not the trailing comma as I'm expecting you want):
finalstring = finalstring.Remove(finalstring.Length -1, 1);
EDIT:
It also looks like you are skipping over every other record by both looping on reader.Read() as well as calling reader.NextResult()
This line:
finalstring = finalstring.Remove(finalstring.Length -1, 1);
is going to remove the last instance of your pipe-delimiter, so if there is only one record (which there appears to be,) you shouldn't see one.
Unless I am missing something...
EDIT
Actually, if you are looking for two records, you are probably missing the second one because you start your loop with while(reader.Read()) and end it with reader.NextResult();. These will both advance the reader, causing you to miss every other record.
EDIT 2
You are also overwriting finalstring on each iteration; you probably want to append to this (making it a StringBuilder would make the most sense for efficiency's sake, if you don't know how many records to expect.)
Your looping structure with the reader appears to have some problems, not the least of which is the reset of finalAnswer within your loop and giving you only a single result combined with using both .Read() and .NextResult:
Suggested fixes...not tested, so all standard caveats apply :) :
Edited per Mark Averius' comment and OP confirmation of original intent:
using (OdbcDataReader reader = com.ExecuteReader()) {
if (reader.HasRows())
{
string finalstring = "";
while (reader.Read()) {
finalstring = finalstring + reader.GetString(9) + ",";
for (int i = 0; i <= 8; i++) {
finalstring = finalstring + reader.GetValue(i).ToString() + ",";
}
finalstring = finalstring + "|";
}
if (finalstring != "") {
finalstring = finalstring.Remove(finalstring.Length -1, 1);
Response.Write(finalstring);
}
}
}