So i have a question. I'm trying do make a function witch returns a number, but the problem is that i can't convert int to string. My functions looks like this:
static string EnemyDmg(EnemyDmg _dmg)
{
string result = "";
int EnemyDmg
= CharAttack - EnemyDefense;
if (EnemyDmg < 1)
EnemyDmg = 4;
result = EnemyDmg;
return result;
}
but it should do this
int EnemyDmg
= CharAttack - EnemyDefense;
if (EnemyDmg < 1)
EnemyDmg = 4;
Console.WriteLine(EnemyName + " takes " + EnemyDmg + " Damage");
has anyone an idea?
PS: The 4 is just a random number.
should be static int EnemyDmg(EnemyDmg _dmg). You should return an int, and convert to string outside the function iif you need that
Anyway, to convert a String s into an int i:
int i = Int32.Parse(s);
to convert an int i into a string s
string s = i.ToString();
string s = ""+i; // more "java-like"
This question is a bit ambiguous; I'm not sure why you've done it this way.
You can convert a C# integer to a string with the .ToString() method, like this:
int a = 12;
string aString = a.ToString();
Console.WriteLine(a);
https://dotnetfiddle.net/sMC3hU
static string toStr(int intInput)
{
string str = intInput.ToString();
return str;
}
}
This code will do it for you. There is no need to use if statement as there is no any specific requirement, it will make more complicated code.
or else
you can direct use ToString parameter if there is an user input just refer to the 3rd line.
I get the error of "Index was outside the bounds of the array", at this line " order.price = Convert.ToDouble(custOrder.Split('$')[1]); ", I have follow the video at here, http://www.youtube.com/watch?v=EbrGoUqbb-A, but I still get the error, I am newbie for C#
public struct Orders
{
public string item;
public double price;
}
const double TAX=0.06;
Orders order = new Orders();
static double subtotal=0;
static double totalTaxes=0;
static double total;
string finalBill = "FINAL BILL:\n";
private void getValues(string custOrder)
{
order.item = custOrder.Split('$')[0];
order.price = Convert.ToDouble(custOrder.Split('$')[1]);
listOutput.Items.Add("Price:" + order.price);
finalBill += "Ordered Item:" + order.item + "\nPrice:" + order.price.ToString("C2") + "\n";
updateBill();
}
private void updateBill()
{
subtotal += order.price;
total += order.price + (order.price * TAX);
totalTaxes += order.price * TAX;
listOutput.Items.Clear();
listOutput.Items.Add(finalBill);
listOutput.Items.Add("Subtotal:" + subtotal.ToString("C2"));
listOutput.Items.Add("Tax:" + totalTaxes.ToString("C2"));
listOutput.Items.Add("Total:" + total.ToString("C2"));
}
private void dropdownSelection(object sender, EventArgs e)
{
if (sender == comboBox1)
getValues(comboBox1.SelectedItem.ToString());
}
custOrder.Split('$')[1]
Stuff that into a variable and use your debugger. Looks like your string custOrder does not contain a '$' character, or it is the last character in the string.
the .Split method, when used on a string, it returns an array. The split parameter is a character that is used as the splitting point.
For example:
String x = "test$one";
var result = x.Split('$') // this returns an array ["test", "one"]
the arrays start their counting from zero, so
result[0] // is "test"
result[1] // is "one"
the splitting character is not included.
In your case, there is no dollar sign, so the split result will be an array with just one string, with the index 0. custOrder.Split('$')[1] does not exist.
Update your getValue method as follows
Check whether you split call really returns 2 array elements to get element of index=1.
Also check whether the returned value of index=1 is really of type double or not. else you will get another error for the string like "asdf$gf" or "asdf$"
private void getValues(string custOrder)
{
double num;
if (custOrder.Split('$').Count() > 1)
{
order.item = custOrder.Split('$')[0];
if (double.TryParse(custOrder.Split('$')[1], out num))
{
order.price = Convert.ToDouble(custOrder.Split('$')[1]);
listOutput.Items.Add("Price:" + order.price);
finalBill += "Ordered Item:" + order.item + "\nPrice:" + order.price.ToString("C2") + "\n";
updateBill();
}
}
}
your string does not contain the '$' text or it only contains 1 of them. try this instead:
string[] splits = custOrder.Split("$".ToCharArray());
if (1 == splits.Length)
order.item = Convert.ToDouble(splits[0]);
else
throw new Exception("Cannot find $ in the customer order");
Depending on what you want you also may have meant Convert.ToDouble(splits[0]); as arrays use zero based indexing not 1 based indexing.
EDIT: changed code based on questioner providing input data sample.
Say we have a string, called source. It contains "New York City - 12A - 1234B"
Here are the rules:
a. We know that the closest two numbers to the beginning of the string should kept, along with the following character and placed into a separate string, called results;
b. We are not certain if this following character will be a number or a letter
c. The formatting of the string itself varies - it could be "NY 12A 1234B"
d. We could care less about anything else!
Now I in my infinite wisdom have crafted this monstrosity. It works but please tell me there is a better way to do this or at best a cleaner, more performance conscious way of doing it.
class Program
{
public static int i = 0;
public static int q = 0;
public static int x = 0;
public static string source = "New York City - 12A - 1234B";
public static string results = "";
public static char[] from_source_char;
public static List<string> from_source_list = new List<string>();
static void Main(string[] args)
{
from_source_char = source.ToCharArray();
foreach (char unit in from_source_char)
{
from_source_list.Add(unit.ToString());
}
Console.WriteLine("Doing while " + i.ToString() + " < " + (from_source_list.Count() - 1).ToString());
while (i < from_source_list.Count() - 1)
{
Console.WriteLine("i is at " + i.ToString());
Console.WriteLine("Examining " + from_source_list[i].ToString());
try
{
q = Convert.ToInt32(from_source_list[i]);
results += from_source_list[i].ToString();
Console.WriteLine("Found part 1!");
x++;
}
catch
{
Console.WriteLine("Disregarding " + from_source_list[i].ToString());
// do nothing
}
if (x == 2)
{
Console.WriteLine("Found final part! " + from_source_char[i+1].ToString());
results += from_source_char[i+1].ToString();
break;
}
i++;
}
Console.WriteLine("Result is " + results.ToString());
Thread.Sleep(999999);
}
}
You could use a Regex with this pattern: #"^.*?(?<numbers>\d{2}\w).*$".
Example:
var f = #"^.*?(?<numbers>\d{2}\w).*$";
var match = Regex.Match("NY 12A 1234B", f);
var result = match.Groups["numbers"].Value;
Another version without regex:
char a = source.First(pos => char.IsDigit(pos));
int b = source.IndexOf(a);
string result = source.Substring(b, 3);
Console.WriteLine(result);
I need to call a program from cmd using an array of numbers(mandatory) and an int time(optional). I have never done this so i'm a bit shaky on the details.
The path is D:\Robert\FactorialConsoleApplication\FactorialConsoleApplication\bin\Debug\FactorialConsoleApplication.exe
As you can tell, the program calculates the factorial of the numbers in the array. The int time is used as a delay in order to display the progress of the stack.
How do I call the program with parameters?
Thanks in advance!
P.S. Here is some of the code
class Program
{
public static void Progress(ProgressEventArgs e)
{
int result = e.getPartialResult;
int stack_value = e.getValue ;
double max = System.Convert.ToDouble(numbers[j]);
System.Convert.ToDouble(stack_value);
double percent = (stack_value / max) * 100;
Console.CursorLeft = 18;
Console.Write(result + " ");
Console.CursorLeft = 46;
Console.Write(System.Convert.ToInt32(percent) + "% ");
}
public static void Calculate(int number, int time=0)
{
Factorial Fact = new Factorial();
Fact.Progression += new Factorial.ProgressEventHandler(Progress);
Console.Write("\n" + "Partial results : ");
Console.CursorLeft = 35;
Console.Write("Progress : ");
int Result = Fact.CalculateFactorial(number, time);
Console.WriteLine(" ");
Console.WriteLine("The factorial of " + number + " is : " + Result);
Console.ReadLine();
}
static int j;
static int[] numbers;
public static void Main(string[] args)
{
int i=0;
bool ok = false;
string line = string.Empty;
numbers = new int[10];
Console.Write("Please insert wait time (0,1 or 2) : ");
int time = int.Parse(Console.ReadLine()) * 1000;
Console.Write("Please insert a number : ");
do
{
line = Console.ReadLine();
if (line != "")
{
i++;
numbers[i] = int.Parse(line);
}
else
{
ok = true;
}
}
while (ok == false);
for (j = 1; j <= i; j++)
{
Calculate(numbers[j],time);
}
}
}
In .net you can use Process.Start from System.Diagnostics to launch an application, you can pass parameters too
For example Process.Start("IExplore.exe", "C:\\myPath\\myFile.htm"); will open Internet Explorer and pass the value "C:\\myPath\\myFile.htm" as parameter to it.For more examplles check the MSDN article on Process.Start method
Update
If in case you are looking to take parameters to your application, when launching itself you don't have to do anything, you are already doing that, the parameter args in your Main method will hold the arguments passed to your application, just try and parse those values in the args array to int array and you are good to go.
Ok, so here is the solution.
I used an args parser like this :
static int extra;
public static void Main(string[] args)
{
foreach (string s in args)
{
extra = int.Parse(s);
Calculate(extra);
}
}
And I changed :double max = System.Convert.ToDouble(numbers[j]);
to :double max = System.Convert.ToDouble(extra);
To call it I open cmd in the directory where the exe is and I type :
Program.exe 3 4 5
It will calculate the factorials of 3, 4 and 5 respectively
Is there any function in c# to shink a file path ?
Input: "c:\users\Windows\Downloaded Program Files\Folder\Inside\example\file.txt"
Output: "c:\users\...\example\file.txt"
Nasreddine answer was nearly correct.
Just specify StringBuilder size, in your case:
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx(
[Out] StringBuilder pszOut,
string szPath,
int cchMax,
int dwFlags);
static string PathShortener(string path, int length)
{
StringBuilder sb = new StringBuilder(length + 1);
PathCompactPathEx(sb, path, length, 0);
return sb.ToString();
}
Jeff Atwood posted a solution to this on his blog and here it is :
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);
static string PathShortener(string path, int length)
{
StringBuilder sb = new StringBuilder();
PathCompactPathEx(sb, path, length, 0);
return sb.ToString();
}
It uses the unmanaged function PathCompactPathEx to achieve what you want.
That looks less human readable to me. Anyway, I don't think there is such a function. split it on the \ character and just keep the first two slots and the last two slots and you have it.
Something like this, although that code is not very elegant
string[] splits = path.Split('\\');
Console.WriteLine( splits[0] + "\\" + splits[1] + "\\...\\" + splits[splits.Length - 2] + "\\" + splits[splits.Length - 1]);
If you want, do insert ellipsis dependent on the length of the path string, then use this code:
TextRenderer.MeasureText(path, Font,
new System.Drawing.Size(Width, 0),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
It will modify path in-place.
EDIT: Be careful with this method. It breaks the rule, saying that strings in .NET are immutable. In fact, the first parameter of the MeasureText method is not a ref parameter, which means that no new string can be returned. Instead, the existing string is altered. It would be careful to work on a copy created with
string temp = String.Copy(path);
You could use something like:
public string ShrinkPath(string path, int maxLength)
{
List<string> parts = new List<string>(path.Split('\\'));
string start = parts[0] + #"\" + parts[1];
parts.RemoveAt(1);
parts.RemoveAt(0);
string end = parts[parts.Count-1];
parts.RemoveAt(parts.Count-1);
parts.Insert(0, "...");
while(parts.Count > 1 &&
start.Length + end.Length + parts.Sum(p=>p.Length) + parts.Count > maxLength)
parts.RemoveAt(parts.Count-1);
string mid = "";
parts.ForEach(p => mid += p + #"\");
return start+mid+end;
}
Or just use Olivers solution, which is much easier ;-).
private string ShrinkPath(string path, int maxLength)
{
var parts = path.Split('\\');
var output = String.Join("\\", parts, 0, parts.Length);
var endIndex = (parts.Length - 1);
var startIndex = endIndex / 2;
var index = startIndex;
var step = 0;
while (output.Length >= maxLength && index != 0 && index != endIndex)
{
parts[index] = "...";
output = String.Join("\\", parts, 0, parts.Length);
if (step >= 0) step++;
step = (step * -1);
index = startIndex + step;
}
return output;
}
I was just faced with this issue as long paths were becoming a complete eye sore. Here is what I tossed together real quick (mind the sloppiness) but it gets the job done.
private string ShortenPath(string path, int maxLength)
{
int pathLength = path.Length;
string[] parts;
parts = label1.Text.Split('\\');
int startIndex = (parts.Length - 1) / 2;
int index = startIndex;
string output = "";
output = String.Join("\\", parts, 0, parts.Length);
decimal step = 0;
int lean = 1;
do
{
parts[index] = "...";
output = String.Join("\\", parts, 0, parts.Length);
step = step + 0.5M;
lean = lean * -1;
index = startIndex + ((int)step * lean);
}
while (output.Length >= maxLength && index != -1);
return output;
}
EDIT
Below is an update with Merlin2001's corrections.
private string ShortenPath(string path, int maxLength)
{
int pathLength = path.Length;
string[] parts;
parts = path.Split('\\');
int startIndex = (parts.Length - 1) / 2;
int index = startIndex;
String output = "";
output = String.Join("\\", parts, 0, parts.Length);
decimal step = 0;
int lean = 1;
while (output.Length >= maxLength && index != 0 && index != -1)
{
parts[index] = "...";
output = String.Join("\\", parts, 0, parts.Length);
step = step + 0.5M;
lean = lean * -1;
index = startIndex + ((int)step * lean);
}
// result can be longer than maxLength
return output.Substring(0, Math.Min(maxLength, output.Length));
}
If you want to write you own solution to this problem, use build in classes like: FileInfo, Directory, etc... which makes it less error prone.
The following code produces "VS style" shortened path like: "C:\...\Folder\File.ext".
public static class PathFormatter
{
public static string ShrinkPath(string absolutePath, int limit, string spacer = "…")
{
if (string.IsNullOrWhiteSpace(absolutePath))
{
return string.Empty;
}
if (absolutePath.Length <= limit)
{
return absolutePath;
}
var parts = new List<string>();
var fi = new FileInfo(absolutePath);
string drive = Path.GetPathRoot(fi.FullName);
parts.Add(drive.TrimEnd('\\'));
parts.Add(spacer);
parts.Add(fi.Name);
var ret = string.Join("\\", parts);
var dir = fi.Directory;
while (ret.Length < limit && dir != null)
{
if (ret.Length + dir.Name.Length > limit)
{
break;
}
parts.Insert(2, dir.Name);
dir = dir.Parent;
ret = string.Join("\\", parts);
}
return ret;
}
}
Nearly all answers here shorten the path string by counting characters.
But this approach ignores the width of each character.
These are 30 'W' characters:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
These are 30 'i' characters:
iiiiiiiiiiiiiiiiiiiiiiiiiiiiii
As you see, counting characters is not really useful.
And there is no need to write your own code because the Windows API has this functionaly since Windows 95.
The name of this functionality is "Path Ellipsis".
The Windows API DrawTextW() has a flag DT_PATH_ELLIPSIS which does exactly this.
In the .NET framwork this is available (without the need to use PInvoke) in the TextRenderer class.
There are 2 ways how this can be used:
1.) Drawing the path directly into a Label:
public class PathLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
if (AutoSize)
throw new Exception("You must set "+Name+".AutoSize = false in VS "
+ "Designer and assign a fix width to the PathLabel.");
Color c_Fore = Enabled ? ForeColor : SystemColors.GrayText;
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, c_Fore,
BackColor, TextFormatFlags.PathEllipsis);
}
}
This label requires you to turn AutoEllipsis off in Visual Studio Designer and assign a fix width to the Label (the maximum width that your path should occupy).
You even see the truncated path in Visual Studio Designer.
I entered a long path which does not fit into the label:
C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe
Even in Visual Studio Designer it is displayed like this:
2.) Shorten the path without drawing it on the screen:
public static String ShortenPath(String s_Path, Font i_Font, int s32_Width)
{
TextRenderer.MeasureText(s_Path, i_Font, new Size(s32_Width, 100),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
// Windows inserts a '\0' character into the string instead of shortening the string
int s32_Nul = s_Path.IndexOf((Char)0);
if (s32_Nul > 0)
s_Path = s_Path.Substring(0, s32_Nul);
return s_Path;
}
The flag TextFormatFlags.ModifyString inserts a '\0' character into the string. It is very unusual that a string is modified in C#.
Normally strings are unmutable.
This is because the underlying API DrawTextW() works this way.
But as the string is only shortened and never will become longer there is no risk of a buffer overflow.
The following code
String s_Text = #"C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe";
s_Text = ShortenPath(s_Text, new Font("Arial", 12), 500);
will result in "C:\WINDOWS\Installer{40BF1E83-20EB-1...\ARPPRODUCTICON.exe"