Pig Latin Translator. C# Homework - c#

Create a GUI application called IGPAY that lets a user enter a word. Then, when the user clicks a button, your program will generate and display the Pig Latin equivalent of that word. (To do this you remove the first letter of the word, then add that letter to the end of the word plus the letters "ay." For example, fish would become ishfay and ball would become allbay.) Make sure the GUI is attractive in appearance and that all labels, textboxes, buttons, and similar are clearly labeled. Hint: store the word in a string and consider using the Substring method. Also remember that the Length property of a string will tell you its length. See pages 79-80 of the text for examples.
Here is the code I came up with. I am new to this language and have a little knowledge with Python, but I'm just not understanding why it throws me an "Out of range exception" error. I am trying to make it so the code accepts any word and displays it in pig Latin.
private void button1_Click(object sender, EventArgs e)
{
string word;
string first;
string rest;
string full;
word = textBox1.Text;
first = word.Substring(0);
rest = word.Substring(1, word.Length);
full = rest + first + "ay";
label2.Text = full;
}

Not sure why you got a downvote, good job declaring this is homework and at least providing some work that you have done. Aside from that, everybody here should appreciate you are wanting to learn.
There are some things I would consider if I were you. In addition to the answer from Phylyp which should fix your exception, you should also handle if the user enters less than two characters, which can also cause exception.
Below I show an example of three things you can do. Not saying it is the best way but it is an option.
Check the entered string to make sure it is at least two characters and if not, prompt user.
Cut down on the amount of string variables and lines of declaration by using one string.Format call.
private void Button1_Click(object sender, EventArgs e)
{
const string suffix = "ay";
string enteredString = textBox1.Text;
//Check the length to make sure it is at least 2
if(enteredString.Length < 2)
{
MessageBox.Show("Please enter at least 2 or more characters");
return;
}
//We get here if 2 or more characters were entered.
//Lets go ahead an process our string
label2.Text = string.Format("{0}{1}{2}",
enteredString.Substring(1),
enteredString.Substring(0,1),
suffix);
}
EDIT - I have edited the answer above to what you actually want to have which is the first substring of just 1 and that will give you everything in the string after the first letter. Basically, you are saying give me the string starting at position 1, or the second letter. Then, the second variable says give me the string starting at position 0 and only for a length of 1 character. This will essentially give you only the first letter. So, this will give you what you want. Couple that with checking to make sure at least two characters are entered, and you shouldn't have any exceptions.
Hope this helps!

first = word.Substring(0, 1);
rest = word.Substring(1, word.Length - 1);
Since the Substring() method is zero-based, word.Length is outside the string. Changing the second argument to word.Length - 1 should avoid the error.
Also, since you need just the first character, the first call to Substring() should have the second argument as 1.
Good you've called this out as homework and have given your attempted code.
(Edited to incorporate Rob's very correct comment about .Substring(1))

Related

Other language word/string split/manipulation issue

Highlight the text searched scenario:
Ex: If I have a word RK and 'r' is searched, I have to highlight first occurance of 'r' i.e., RK. In the background it is like
< b >R< /b >K.
Similarly I have to highlight ம in மொ. Hence I am trying to find the position of ம in மொ and performing highlighting operation.
Here I am getting the text after manipulation as
< b >ம< /b >ொ and hence it is displayed as ம ொ
The code that I used for string manipulation and highlighting:
formattedString = string.Empty;
searchStringLength = searchString.Length;
formattedString += inputString.Substring(0, find);
formattedString += "<b>" + inputString.Substring(find, searchStringLength) + "</b>";
formattedString += inputString.Substring(find + searchStringLength);
The example is just for Tamil word, any suggestions to make it work for all other languages other than english?
I do not know Tamil. Looking at your question, the input string should be three letter string.
Probably, you are setting your find variable something like
find = inputString.IndexOf("ம");?
somewhere in your code.
The Tamil word மொ is not being counted as three letter word. Visual Studio is handling it as single letter while மொ.Length returns 2. ToCharArray() also returns array of two characters. That is why, IndexOf is always returning 0.
Your comment on question:
since ம + ொ = மொ, the ம find was returning true always. Now after this solution, ம find will return false and hence I don't have to highlight. Only if மொ is entered to find, it matches exactly and I can highlight.
I do not think problem is in SubString. The IndexOf needs to be handled tactically.

How to get index of any charcter in unicode string

I having a string variable which basically holds value of corresponding English word in the form of Chinese.
String temp = "'%1'不能输入步骤'%2'";
But when i want to know wether the string having %1 in it or not by using IndexOf function
if(temp.IndexOf("%1") != -1)
{
}
I am not getting true even if it contain %1.
So is there any issue due to Chinese charters or any thing else.
Pls suggest me how i can get the index of any charter in above case.
That is because %1 is not equal to %1 What you want to do in this case as workaround is select the symbols out of string you have like
var s = "'%1'不能输入步骤'%2'";
var firstFragment = s.Substring(1, 2); // this should select you %1
and then do
if(temp.IndexOf(first) != -1){
}
Comments gave the answer. Use the same percent character, so instead of:
"%1"
use:
"%1"
Or, if you find that problematic (your source code is in a "poor" code page, or you fear the code is hard to read when it contains full-width characters that resemble ASCII characters), use:
"\uFF051"
or even:
"\uFF05" + "1"
(concatenation will be done by the C# compiler, no extra concatting done at run-time).
Another approach might be Unicode normalization:
temp = temp.Normalize(NormalizationForm.FormKC);
which seems to project the "exotic" percent char into the usual ASCII percent char, although I am not sure if that behavior is guaranteed, but see the Decomposition field on Unicode Character 'FULLWIDTH PERCENT SIGN' (U+FF05).

0x202A in filename: Why?

I recently needed to do a isnull in SQL on a varbinary image.
So far so (ab)normal.
I very quickly wrote a C# program to read in the file no_image.png from my desktop, and output the bytes as hex string.
That program started like this:
byte[] ba = System.IO.File.ReadAllBytes(#"‪D:\UserName\Desktop\no_image.png");
Console.WriteLine(ba.Length);
// From here, change ba to hex string
And as I had used readallbytes countless times before, I figured no big deal.
To my surprise, I got a "NotSupported" exception on ReadAllBytes.
I found that the problem was that when I right click on the file, go to tab "Security", and copy-paste the object-name (start marking at the right and move inaccurately to the left), this happens.
And it happens only on Windows 8.1 (and perhaps 8), but not on Windows 7.
When I output the string in question:
public static string ToHexString(string input)
{
string strRetVal = null;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (char c in input)
{
sb.Append(((int)c).ToString("X2"));
}
strRetVal = sb.ToString();
sb.Length = 0;
sb = null;
return strRetVal;
} // End Function ToHexString
string str = ToHexString(#"‪D:\UserName\Desktop\cookie.png");
string strRight = " (" + ToHexString(#"D:\UserName\Desktop\cookie.png") + ")"; // Correct value, for comparison
string msg = str + Environment.NewLine + " " + strRight;
Console.WriteLine(msg);
I get this:
202A443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67
(443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67)
First thing, when I lookup 20 2A in ascii, it's [space] + *
Since I don't see neither a space nor a star, when I google 20 2A, the first thing I get is paragraph 202a of the german penal code
http://dejure.org/gesetze/StGB/202a.html
But I suppose that is rather an unfortunate coincidence and it is actually the unicode control character 'LEFT-TO-RIGHT EMBEDDING' (U+202A)
http://www.fileformat.info/info/unicode/char/202a/index.htm
Is that a bug, or is that a feature ?
My guess is, it's a buggy feature.
The issue is that the string does not begin with a letter D at all - it just looks like it does.
It appears that the string is hard-coded in your source file.
If that's the case, then you have pasted the string from the security dialog. Unbeknownst to you, the string you pasted begins with the LRO character. This is an invisible character which tales no space, but tells the renderer to render characters from left-to-right, ignoring the usual rendering.
You just need to delete the character.
To do this, position the cursor AFTER the D in the string. Use the Backspace or Delete to Left key <x] to delete the D. Use the key again to delete the invisible LRO character. One more time to delete the ". Now retype the " and the D.
A similar problem could occur wherever the string came from - e.g. from user input, command line, script file etc.
Note: The security dialog shows the filename beginning with the LRO character to ensure that characters are displayed in the left-to-right order, which is necessary to ensure that the hierarchy is correctly understood when using RTL characters. e.g. a filename c:\folder\path\to\file in Arabic might be c:\folder\مسار/إلى/ملف. The "gotcha" is the Arabic parts read in the other direction so the word "path" according to google translate is مسار, and that is the rightmost word, making it appear is if it was the last element of the path, when in fact it is the element immediately after "c:\folder\".
Because security object paths have an hierarchy which is in conflict with the RTL text layout rules, the security dialog always displays RTL text in LTR mode. That means that the Arabic words will be mangled (letters in wrong order) on the security tab. (Imagine it as if it said "elif ot htap"). So the meaning is just about discernable, but from the point of view of security, the security semantics are preserved.
Filenames that contain RLO/LRO overrides are commonly created by malware. Eg. “exe” read backwards spells “malware”. You probably have an infected host, or the origin of the .png is infected.
This question bothered me a lot, how would it be possible that a deterministic function would give 2 different results for identical input? After some testing, it turns out that the answer is simple.
If you look through it in your debugger, you will see that the 'D' char in your #"‪D:\UserName\Desktop\cookie.png" (first use of Hex function) is NOT the same char as in #"D:\UserName\Desktop\cookie.png" (second use).
You must have used some other 'D'-like character, probably by unwanted keyboard shortcut or by messing with your Visual Studio character encoding.
It looks exactly the same, but in reality it's not event a single char 9try to watch the c variable in your toHex function.
if you change to the normal 'D' in your first example, it will work fine.

Is there a way to keep Console.ReadLine in memory for later referral in C#?

I want to write an if statement that would essentially say, "If what was entered into the last Console.ReadLine() method contained an "!""...do something.
So, I've got a method:
static void Operations(StringBuilder bleh, int ops, int count, string str)
{
for (int i = 0; i < ops; i++)
{
bleh.Append(Console.ReadLine()); // Potential value of "ops" is > 100,000
if (bleh.ToString().IndexOf("!") != -1)
{
bleh.Replace("!", "");
}
else
{
bleh.Remove(0, 1);
bleh.Replace("^", "");
}
...
On every readLine() there is either a "!" + a letter entered or just a "^". If a "^" is entered the stringbuilder's first index char is removed as well as the "^". If a "!" is entered, just the "!" is removed, but the letter remains.
My code seems slow because after I've appended a new string from the ReadLine(), it has to search for a "!" or a "^" in a potentially huge string on every iteration of the loop, and then search again to remove it. It would be much better if I could keep track of when the "^" and "!" were entered thereby allowing me to replace them by using the index values:
bleh.Replace(counter, 1)
Getting the index values here are a little tricky to get at since the size of the stringbuilder is growing and shrinking depending on the entered values.
This brings up an interesting question: How is something like, "StringBuilder.Replace("abc", "a") done? For a string that's say 10,000 characters long, is it searching from the beginning of the string and "scrolling" through it to find "abc"? Since the .Append method is putting the "!2", for example, at the end, the the performance is compromised.
Is there an easy answer that would increase performance?
It seems like ! and ^ are being replaced as they are being inputted. That is, beyond the current input line, those characters cannot appear at all in StringBuilder bleh.
If that is the case, then you should only need to search/replace in the current input string.
meh = Console.ReadLine();
if (meh.ToString().IndexOf("!") != -1)
meh.Replace("!", "");
else
{
bleh.Remove(0, 1);
meh.Replace("^", "");
}
bleh.Append(meh);
If you still need to know whether an input line had a particular character (or similar) after doing the replace, I would recommend storing those lines in a List of Strings rather than all together in a StringBuilder. This way, you can store different input types into different lists or use objects to hold the string and some metadata.
If this is not sufficient, then you might have to resort to keeping an index of the locations of special characters. Search the input string, get indices of relevant characters (plus the StringBuilder's length), then append the input string. Store those indices in a list for later lookup.

c# Split sentence

Is it possible to split this combined words into two?
ex: "Firstname" to
"First"
"Name"
I have a bunch of properties eg FirstName,LastName etc. and I need to display this on my page. Thats why I need to separate this property name to display into more appropriate way.
Your aim is fuzzy.
If properties alway have Uppercase letter, you can find positions of all uppercase letters in the word and devide it by that positions.
If uppercase letters is not guaranteed, the best way would be to create transform table. The table would be define pairs of initial property name and resulting text. In this way you will have simple map for transormation
Edit: OP specified that he needs to split property names
If you follow CamelCase naming convention for properties (i.e. "FirstName" instead of "Firstname"), you can split the words by upper case characters quite easily.
string[] SplitByCaps(string input)
{
StringBuilder output = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (i > 0 && Char.IsUpper(c))
output.Append(' ');
output.Append(c);
}
return output.ToString().Split(' ');
}
Orinal answer:
I would say, for practical purposes, it's not possible to do this for any arbitrary string.
Of course it is possible to write a program to do this, but whatever your actual needs are, that program would be overkill. There might also be libraries that already do this, but they would be so heavy that you wouldn't want to take a dependency on them.
Any program which could achieve this would have to have know all words in the English language (let's not even consider multilanguage solutions). You would also require an intelligent lexical parser, because for any word, there might be more than one possible way to split it.
I suggest you look into some other way to solve your particular problem.
Unless you have a dictionary of all 'single' words the only solution I can think of is to split on upper letters:
FirstName -> First Name
The problem will still exist for UIFilter -> UI Filter.
You can use substring to get the first 5 characters from the string. Then replace the first five characters in original string to blank.
string str = "Firstname";
string firstPart = str.Substring(0,5); // "First"
string secondPart = str.replace(firstPart,""); // "name"
If you want to make it generic for any word to be split, then you need to have some definite criteria on which you can divide the word into parts. Without definite criteria, it is not possible to split the string as expected by you.

Categories

Resources