Writing scope ({) into string in console app - c#

I am trying to write a code generator using a c# console application. Now when I type this, I receive an error:
Console.WriteLine("sphere {{0}{1} {2} texture{Gold_Metal}}",
pre, i.ToString(), sprad.ToString());
It says "input in wrong format" I have checked that all the variables were strings, and they are. When I tried
Console.WriteLine("sphere {0}{1} {2} textureGold_Metal",
pre, i.ToString(), sprad.ToString());
It worked perfectly fine. Is there a way to fix this?

Assuming you want a literal { inserted into the stream, you need to escape a your { with yet another brace thus:
Console.WriteLine("sphere {{{0}{1} {2} ...
^^
||-- see here.
Similarly for the end-brace, this is detailed in the MSDN string formatting FAQ here. The sequence {{ becomes { and }} becomes }.
From what I understand your intent to be, the full statement in your specific case would be:
Console.WriteLine("sphere {{{0}{1} {2} texture{{Gold_Metal}}}}",
pre, i.ToString(), sprad.ToString());
which should give you something like:
sphere {<Arg0><Arg1> <Arg2> texture{Gold_Metal}}

You need to use {{ to "escape" the curly brace. Writeln interprets {{0} as 'literal {' followed by 0}, resulting in the wrong format error.

Change what you have to write this and see if it works.. also make sure that you are converting the variable types where you have .ToString(); would need to know what the actual declared types are.. paste the code in where you have declared pre, sprad, and i
Console.WriteLine(string.Format("sphere {0}{1} {2} textureGold_Metal",
pre, i.ToString(), sprad.ToString()));

Related

Console WriteLine(var, var); not displaying second variable?

I'm writing a little text-based adventure in the console as one of my first projects in C#.
At a certain point, I want to do the following:
Console.WriteLine(intro);
var name = Console.ReadLine();
Console.Clear();
Console.WriteLine(replyOne, name, replyTwo);
However, on that last line, only the first variable (replyOne) is displayed. How can I display all the values?
Depends on what's on replyOne, but you are using a Console.WriteLine overload that takes a format string as the first argument and a number of objects for substitution of that format string (this one). That's what's called Composite Formatting in .NET
If what you want to do is concatenate the strings, you can do it in several ways:
Pass only one string to Console.WriteLine:
Console.WriteLine(replyOne + name + replyTwo);
Use a format string... this would use the same overload you are using now, but passing a formatting string for substitution on the first argument:
Console.WriteLine("{0}{1}{2}", replyOne, name, replyTwo);
Use an interpolated string (C# 6 and up only)
Console.WriteLine($"{replyOne}{name}{replyTwo}");
In the multi-argument overloads of the Console.WriteLine the first parameter is supposed to be a format string, and everything else as a substitution values.
See Console.WriteLine Method (String, Object) for details.
If you want Console.WriteLine to output a formatted string the first argument has to be the string that contains the placeholders that define the formatting. So assuming you just want to output the three strings consecutively, you'll need something like this:
Console.WriteLine("{0} {1} {2}", replyOne, name, replyTwo);
which will output the three strings separated by spaces.
You can replace the spaces by commas, newlines (\n) or tabs (\t) to get the formatting you need.
Try this instead:
Console.WriteLine(replyOne + name + replyTwo);
Or something similar.
As you're calling the method right now, it's treating the replyOne value as the format for the output, not an individual output item. And of course, your format doesn't have a {0} or {1} for the format arguments in the call, name and replyTwo, so they are omitted.
You can just concatenate the output text yourself, as above, as use that as the entire format (without any format arguments at all).
There are, of course, lots of other options for formatting the output. The above fits what you've posted so far.
Console.WriteLine("{0},{1},{2}",replyOne,name,replyTwo);

C# string format arguments

I know that the following syntax works
String.Format("Today is {0}, {1}", day,month);
I was just curious how this format works?
String.Format("Today is {day}, {month}", day,month);
How does C# interpret replacing number with user defined names?
String.Format("Today is {day}, {month}", day,month);
Does not work, it throws a System.FormatException.
According to the documentation the replacement fields must be in the format { index[,alignment][:formatString]} which your 2nd example does not follow.
The items in the {} must be integers beginning at 0 and match the number of variables in the second argument of .Format(...) method. Download a program, such as LinqPad, to run test scripts such as this.

How to in C# keep a set number of letters for a string in console writeline

Ok so basically I want something like
Console.WriteLine(
"{0}: {1}/{2}hp {3}/{4}mp {5}",
character.Identifier,
character.CurrentHealth,
character.MaxHealth,
character.CurrentMagic,
character.MaxMagic,
character.Fatigue
);
and then have the character.Identifier (which is basically a name) have a set number of letters which it will replace with spaces if needed so that in might print
Josh: 20/20hp 20/20mp 3
or
J: 20/20hp 20/20mp 3
but the HP and then mp and everything else is always in line.
I am aware that its probably one of the {0:} but i couldn't figure out one that works
The second argument in the {0} notation can give you a fixed width field, so if you wanted the identifier (name) to always be 10 characters long and be left justified, you would use {0,-10}
MSDN is a good resource for this kind of question too, if you read the documentation for String.Format it has an example of a fixed width table that might be similar to what you want.
Also, as Hogan's answer correctly points out, you would have to append the : to the string outside of the format string if you want it right next to the name.
You can right pad a string with spaces by using:
character.Identifier.PadRight(10);
This should give you the format you are after.
I believe this will do what you want:
const int colWidth = 10;
Console.WriteLine("{0,-"+colWidth.ToString()+"}{1,-"+colWidth.ToString()+"}{2,-"+colWidth.ToString()+"}{3}",
(character.Identifier+":").PadRight(colWidth+1).Remove(0,colWidth),
(character.CurrentHealth+"/"+character.MaxHealth+"hp").PadRight(colWidth+1).Remove(0,colWidth),
(character.CurrentMagic+"/"+character.MaxMagic+"mp").PadRight(colWidth+1).Remove(0,colWidth),
(character.Fatigue,colWidth));
This will add spaces to the end of string and then truncate the result.
See the docs for String.Format
NOTES
I append the : to the name outside of the format string and I "merge" the hp and mp sections and then put them in a column.

How to include Variables in Localized Strings?

I'm trying to display a message to the user along the lines of:
"User 5 could not be added"
But how can I add variables to a string that is being placed in a .resx file? I've trying searching for things like "Variables in Localization" "Globalization with Variables" etc, but came up dry.
If I weren't localizing I would write:
Console.Write("User " + userNum + " could not be added");
How can this be accomplished with resources?
You can't do this directly.
What you can do is place a token - a specific string that can be replaced with string.Replace with the value of the variable.
A good candidate for this would be the built in string formatting:
Console.Write(string.Format("User {0} could not be added", userNum));
Assuming userNum has the value 5, the result would be:
User 5 could not be added
You can localize this string with the composite format specifiers.
In teams where I've done internationalization, we generally also created a resource for the format string, something like USER_COULD_NOT_BE_ADDED_FORMAT, and called String.Format (or your environment's equivalent) by passing that resource's value as the format pattern.
Then you'll do Console.Write(String.Format(resourceManager.GetString("USER_COULD_NOT_BE_ADDED_FORMAT"), userNum));
Most localizers either have training in the format strings used by the system they are localizing, or they are provided with guidance in the localization kit that you provide them. So this is not, for example, as high a barrier as making them modify code directly.
You generally need to add a loc comment to the resource ID to explain the positional parameters.
Use Composite Formatting like so:
Console.Write("User {0} could not be added", userNum);
This way you would localize "User {0} could not be added".
you can do that its simple
new lets see how
String.Format(Resource_en.PhoneNumberForEmployeeAlreadyExist,letterForm.EmployeeName[i])
this will gave me dynamic message every time
by the way I'm useing ResXManager
I would use string.Format
http://msdn.microsoft.com/en-us/library/system.string.format.aspx
Console.Write(string.Format("User {0} could not be added", userNum));

Format a Resource string into another one?

What would be the best way to accomplish something like this?
Suppose I have the following pair of Resource strings.
BadRequestParameter: Potential bad request aborted before execution.
RequiredParameterConstraint: {0} parameter requires a value. {1}
And suppose I want to set {1} on the second one, to the value of BadRequestParameter. I could easily do that using string.Format. But now suppose I have lots of Resource strings like the second one, all of which include some other Resource string in them.
What would be the best way to code this? Is using string.Format repeateadly in each case really all that I can do?
Update
I'll try to explain myself better. These are the resource strings I actually have:
BadRequestParameter Potential bad request aborted before execution.
EmptyVector Vectorized requests require at least one element. {0}
OverflownVector Vectorized requests can take at most one hundred elements. {0}
RequiredParamConstraint {0} parameter requires a value. {1}
SortMinMaxConstraint {0} parameter value '{1}' does not allow Min or Max parameters in this query. {2}
SortRangeTypeConstraint Expected {0} parameter Type '{1}'. Actual: '{2}'. {3}
SortValueConstraint {0} parameter does not allow '{1}' as a value in this query. {2}
I'd like to avoid writing the string in BadRequestParameter at the end of each of those lines. Therefore, I added a format at the end of those strings. The issue now is that I'd like to somehow auto-reference {x} to BadRequestParameter, in order to avoid having to make calls like
string.Format(Error.EmptyVector, Error.BadRequestParameter);
I have lots of Resource strings like the second one, all of which include some other Resource string in them.
Instead of storing pre-made format strings ready for use, you could store raw material for building real format strings, and add code to expand them pro grammatically before use. For example, you could store strings like this:
BadRequestParameter: Potential bad request aborted before execution.
SupportNumber: (123)456-7890
CallTechSupport: You need to call technical support at {SupportNumber}.
RequiredParameterConstraint: {{0}} parameter requires a value. {BadRequestParameter} {CallTechSupport}
Of course passing these strings to string.Format as-is is not going to work. You need to parse these strings, for example with RegExps, and find all instances where you have a word between curly braces, instead of a number. You could then replace each word with its sequence number, and produce an array of parameters based on the names that you find between curly braces. In this case, you will get these two values (pseudocode):
formatString = "{{0}} parameter requires a value. {0} {1}";
// You replaced {BadRequestParameter} with {0} and {CallTechSupport} with {1}
parameters = {
"Potential bad request aborted before execution."
, "You need to call technical support at (123)456-7890."
};
Note: Of course, producing this array of parameters required recursion.
At this point, you can invoke string.Format to produce your final string:
var res = string.Format(formatString, parameters);
This returns the string that has resource strings pre-replaced for your callers:
"{0} parameter requires a value. Potential bad request aborted before execution. You need to call technical support at (123)456-7890."
The callers can now use this string for formatting, without bothering with other resource values.
Yes :-) unless you want to make a helper method that is shorter, but that would really just be for convenience sake
public static string f(string format, params object[] p)
{
return string.Format(format, p);
}
IF you treat the argument indicators {#} as wild cards then why would it make sense for you to pre-fill them inside of your resource.
I see absolutely nothing wrong with
String.Format(RequiredParamterConstraint, "something", BadRequestParameter);

Categories