for (int s = 1; s <= NumComponents;s++ )
{
fname = #"C:\Users\Johaira\Documents\Visual Studio 2010\Projects\SpecialProblem1\SpecialProblem1\bin\Debug\" ;
fname2 = fname + string.Format("{0:00}.png", s);
Bitmap inputImage = new Bitmap(fname2);
//do some image processing here...for example thinning
}
I am doing image processing in c#. I have this for loop that processes each image from a directory.. the file names of my images are numbers.. but I cannot load them.. what do I do..
It works when it is not in a loop..when I call
Bitmap inputImage = new Bitmap(#"C:\Users\Johaira\Documents\Visual Studio 2010\Projects\SpecialProblem1\SpecialProblem1\bin\Debug\1.png");
It is working fine..in one image only..but I want it to be dynamic so what do I do? Pls help me..thank you.
Your code uses
string.Format("{0:00}.png", s)
to produce the filename. For an input value of 1 this results in the string "01". That's because your format string explicitly includes a leading zero.
So the problem boils down to your conversion from integer to string. You want a conversion that does not have leading zeros. For example:
s.ToString()
Or if you want the convenience of converting the number, and adding on the extension in one go, then
string.Format("{0}.png", s)
The format item has the following syntax:
{ index[,alignment][ :formatString] }
So, since {0} contains just the index, and omits the formatString, the default formatting is performed by calling ToString() on the object. So, the above call to string.Format() is just a convenient way to write:
s.ToString() + '.png'
As a piece of general advice, I suggest you take some time to learn how to get the most out of your debugger. Had you inspected the value of your file name variable you would immediately have seen the erroneous leading zero. You will benefit greatly from learning how to use the debugger to investigate problems with your code.
Assuming your filenames are for example 1.png, 2.png etc:
for (int s = 1; s <= NumComponents;s++ ) {
const string fname = #"C:\Users\Johaira\Documents\Visual Studio 2010\Projects\SpecialProblem1\SpecialProblem1\bin\Debug\" ;
var fname2 = Path.Combine(fname,String.Format("{0}.png",s));
using (Bitmap inputImage = new Bitmap(fname2)) {
// Process image
}
}
The reason your code didn't work originally was you were using {0:00} which would have padded with 0 you loop value.
Related
I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".
I have a text file, which I am trying to insert a line of code into. Using my linked-lists I believe I can avoid having to take all the data out, sort it, and then make it into a new text file.
What I did was come up with the code below. I set my bools, but still it is not working. I went through debugger and what it seems to be going on is that it is going through the entire list (which is about 10,000 lines) and it is not finding anything to be true, so it does not insert my code.
Why or what is wrong with this code?
List<string> lines = new List<string>(File.ReadAllLines("Students.txt"));
using (StreamReader inFile = new StreamReader("Students.txt", true))
{
string newLastName = "'Constant";
string newRecord = "(LIST (LIST 'Constant 'Malachi 'D ) '1234567890 'mdcant#mail.usi.edu 4.000000 )";
string line;
string lastName;
bool insertionPointFound = false;
for (int i = 0; i < lines.Count && !insertionPointFound; i++)
{
line = lines[i];
if (line.StartsWith("(LIST (LIST "))
{
values = line.Split(" ".ToCharArray());
lastName = values[2];
if (newLastName.CompareTo(lastName) < 0)
{
lines.Insert(i, newRecord);
insertionPointFound = true;
}
}
}
if (!insertionPointFound)
{
lines.Add(newRecord);
}
You're just reading the file into memory and not committing it anywhere.
I'm afraid that you're going to have to load and completely re-write the entire file. Files support appending, but they don't support insertions.
you can write to a file the same way that you read from it
string[] lines;
/// instanciate and build `lines`
File.WriteAllLines("path", lines);
WriteAllLines also takes an IEnumerable, so you can past a List of string into there if you want.
one more issue: it appears as though you're reading your file twice. one with ReadAllLines and another with your StreamReader.
There are at least four possible errors.
The opening of the streamreader is not required, you have already read
all the lines. (Well not really an error, but...)
The check for StartsWith can be fooled if you lines starts with blank
space and you will miss the insertionPoint. (Adding a Trim will remove any problem here)
In the CompareTo line you check for < 0 but you should check for == 0. CompareTo returns 0 if the strings are equivalent, however.....
To check if two string are equals you should avoid using CompareTo as
explained in MSDN link above but use string.Equals
List<string> lines = new List<string>(File.ReadAllLines("Students.txt"));
string newLastName = "'Constant";
string newRecord = "(LIST (LIST 'Constant 'Malachi 'D ) '1234567890 'mdcant#mail.usi.edu 4.000000 )";
string line;
string lastName;
bool insertionPointFound = false;
for (int i = 0; i < lines.Count && !insertionPointFound; i++)
{
line = lines[i].Trim();
if (line.StartsWith("(LIST (LIST "))
{
values = line.Split(" ".ToCharArray());
lastName = values[2];
if (newLastName.Equals(lastName))
{
lines.Insert(i, newRecord);
insertionPointFound = true;
}
}
}
if (!insertionPointFound)
lines.Add(newRecord);
I don't list as an error the missing write back to the file. Hope that you have just omitted that part of the code. Otherwise it is a very simple problem.
(However I think that the way in which CompareTo is used is probably the main reason of your problem)
EDIT Looking at your comment below it seems that the answer from Sam I Am is the right one for you. Of course you need to write back the modified array of lines. All the changes are made to an in memory array of lines and nothing is written back to a file if you don't have code that writes a file. However you don't need new file
File.WriteAllLines("Students.txt", lines);
I'm new to programming, so please forgive my naive question .
I have double[ ] array, I manage to write it to text file using the code below:
using (System.IO.StreamWriter outfile = new System.IO.StreamWriter(#"C:\Seasonality.txt") )
{
for (int raw = 1; raw <54; raw++)
{
outfile.Write("{0} ",array[raw]);
}
}
The output text file (1 raw) consist of 54 records separated by space as demonstrated below:
1.323 2.3443 2.367 5.3453 0.3432 1.754 ........etc
What I'm trying to achieve is a function where I read a value by passing its index, i.e. index =1 for the first value in the file, or index =5 for the fifth value in the file etc..
Double GetValue (int index)
{
.....
}
P.S: please suggest if you think that changing output file structure to one value per line will ease the task.
Thanks in advance
For completeness, since you mention the option of splitting into lines per value - if you did that it would be:
var item = File.ReadLines(path).Skip(index-1).First();
(plus parsing the final value)
You're going to need to do a few things.
First: Load the file into a string. You can use File.ReadAllText() or something similar (use the IO streams if you want).
Next you need to parse your data. You have your items separated by spaces so you're going to want to use stringName.split(' '); where stringName is the variable you use for the file you just loaded and the ' ' represents the character for space (not sure how new you are but " " is a string and ' ' is a character).
Finally you want to grab the correct index, which should actually be the same as you saved the array since you're just reloading it.
Hope this helps!
Edit: Forgot that you'll need to do the double.parse thing at the end to return your value, as others have shown.
you can do as below,
double GetValue(int index)
{
return double.Parse(File.ReadLines(path).First().Split()[index-1]);
}
Note:
better you can do more validations for the results of read line, split having enough items to take by given index and use double.TryParse to convert.
double GetValue(int index)
{
return double.Parse(System.IO.File.ReadAllLines(your file)[0].Split(' ')[index]);
}
I have a function in a class called Function, like below:
public int SearchedRecords(String [] recs)
{
int counter = 0;
String pat = "-----";
String[] records = recs;
foreach (String line in records)
{
if (line.Contains(pat) == true)
{
counter++;
}
}
return counter;
}
And I am calling this method from my main class this way:
String [] file = File.ReadAllLines("C:/Users.../results.txt");
int counter = Function.SearchedRecords( []file);
But I get an error saying:
;expected
What is wrong?
Another question: The function above is counting from a file all the lines with the pattern ----- in them (even if with more dashes, or if the line has some chars before or after the dashes). Am I right?
It's something like the patterns in Java so maybe there is an other way.
Can you enlighten me?
Remove the [] from your parameter.
e.g.
int counter = Function.SearchedRecords(file);
And yes, your assumption about the behavior of the Contains method is correct - you'll match any line containing five consecutive dashes, regardless of what characters are before or after them.
If you want to parse for exactly five dashes, with nothing before or after them I suggest looking into the RegEx class (regular expressions).
Change
int counter = Function.SearchedRecords( []file);
to
int counter = Function.SearchedRecords(file);
and yes, this will work, for that string.
However Contains is case sensitive, if you were matching on a name, or another string with alphabetic characters, the case would have to be identical to match e.g. line.Contains("Binary Worrier") will not match a string "Hello binary worrier".
Also, reading the entire file into memory is fine if you know that the file will always be small, this method gets less efficient the larger the file.
Better to always use something like System.IO.StreamReader or System.IO.File.ReadLines (available in .Net 4 and later), these allow you to consume the file one line at a time. e.g.
using (var reader = new System.IO.StreamReader("MyFile.txt"))
{
while(!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains(pattern))
counter++;
}
}
Change it to
int counter = Function.SearchedRecords(file);
Remove '[]' from a method call. Yes, your function seems to count what you want.
First of all you need to create an instance of function class and then run the function. Hope following code helps
Function fb = new Function();
int counter = fb.SearchedRecords(file);
Right now, you are using SearchRecords as an static function of a static class which doesn't require instantiation.
You can do this in a shorter way using LINQ:
int counter = file.Count(line => line.Contains("-----"));
I am working on a file parser, and this bit of code is not giving me what I want. Before I go any farther, I should mention that I did not write this program, I am only editing the source to fix this specific problem. Also, I can compile the code, so that is not a problem (you know how downloaded programs always have compile errors). Here's the code.
case EsfValueType.Binary4E: //System.String[]
{
int size = (int)(this.reader.ReadUInt32() - ((uint)this.reader.BaseStream.Position));
var strings = new string[size / 4];
for (int i = 0; i < size / 4; i++)
strings[i] = this.stringValuesUTF16[this.reader.ReadUInt32()];
esfValue.Value = strings.ToString();
break;
}
Now, I added the .ToString(); part to the above line, but it made no difference. The problem is that esfValue.Value ends up with System.String[] as it's value, and I want the value of the System.String object. If you can make sense out of this and tell me what is wrong, it would be appreciated.
The program name is ESF Editor 1.4.8.0.
case EsfValueType.Binary4E: //System.String[]
{
int size = (int)(this.reader.ReadUInt32() - ((uint)this.reader.BaseStream.Position));
var strings = new StringBuilder();
for (int i = 0; i < size / 4; i++)
{
strings.Append(this.stringValuesUTF16[this.reader.ReadUInt32()]); //or AppendLine, depending on what you need
}
esfValue.Value = strings.ToString();
break;
}
The strings variable is an array of strings - the Array class does not override the default ToString() implementation which returns the type of the object.
You need to concatenate all the strings in the array - either looping and concatenating or using LINQ and assign the resulting string to esfValue.Value. Of course, this assumes you want the values all in one string, one after the other.
Your issue is that strings isn't a single string, its an array of strings. As a result your call to ToString is calling Object.ToString(), which returns the type of the object.
Maybe you want something like
esfValue.Value = strings.Aggregate((acc, next) => acc + next)
which will simply concatenate all the strings together.
When you do a .ToString() on a class that doesn't override the .ToString() base method to return a custom string (which string[] doesn't), you're always going to get the type's namespace/class as the result.
Arrays, in and of themselves, don't have values. What value are you trying to get? Are you trying to join the array into a single, character-delimited string? If so, this would work:
esfValue.Value = string.Join(",", strings);
Just replace the , with whatever character you want to delimit the array with.
I think you just need to join the string values contained in the string array. In order to do so, you need to call String.Join and pass the string separator and the string array. It returns a single System.String.