Problems with if and else if, c# - c#

I'm trying to make a program that converts japanese characters into english characters but I have a weird problem and I cant figure out what how to solve it, I did find out what caused it though.
I'm using a dataset and I'm using this code to convert the characters
My problem is that it doesn't want to convert certain characters, and the characters it doesn't want to convert are based on what I set here:
// Sets fromtype to the type the character(s) currently is/are
string fromtype = "";
if (CharacterTable.Select("Romaji like '%" + character + "%'") != null)
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana like '%" + character + "%'") != null)
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana like '%" + character + "%'") != null)
{
fromtype = "Katakana";
}
If I change every individual line to "if", then it doesn't want to recognise romaji characters, if i set it to "else if" like right now, it sees.
Here is the full code:
DataSet CharacterDatabase = new DataSet();
DataTable CharacterTable = CharacterDatabase.Tables.Add();
//-- Add columns to the data table
CharacterTable.Columns.Add("Romaji", typeof(string));
CharacterTable.Columns.Add("Hiragana", typeof(string));
CharacterTable.Columns.Add("Katakana", typeof(string));
//-- Add rows to the data table
CharacterTable.Rows.Add("a", "?", "?");
// Sets fromtype to the type the character(s) currently is/are
string fromtype = "";
if (CharacterTable.Select("Romaji like '%" + character + "%'") != null)
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana like '%" + character + "%'") != null)
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana like '%" + character + "%'") != null)
{
fromtype = "Katakana";
}
// generates a new variable to store the return in
DataRow[] filteredRows = CharacterTable.Select(fromtype + " like '%" + character + "%'");
// Return the converted character in the requested type
foreach (DataRow row in filteredRows)
{
if (RequestedCharType == 1)
{
return row["Romaji"].ToString();
}
if (RequestedCharType == 2)
{
return row["Hiragana"].ToString();
}
if (RequestedCharType == 3)
{
return row["Katakana"].ToString();
}
}
// if it couldn't find the character, return the original character
return character;

You need to consider what happens if a character matches multiple types. It is possible that regardless of the if or if else, you choose a fromtype that doesn't have a matching result in the database.
You could consider some sort of scoring mechanism, where you query each type, and if the character matches multiple types, you take into consideration which types have replacements available.

You assume that DataTable.Select() returns a null when there is no match. It doesn't, it returns an empty array. Your test should look like this:
if (CharacterTable.Select("blabla").Length > 0) { // etc.. }

Related

How do i working with Arrays in a While loop?

I have tried to wipe this data while trying to export a database into my program.
The basic problem is that I do not know why he can not use LIKE in my SQL statement.
So I wanted to catch all DataRows and write them into an array, which I can edit later.
The program throws an exception:
Error message: System.IndexOutOfRangeException: "The index was outside the array area."
If I did something unusual or wrong in my Post I sincerely apologies, this is my first entry in this forum.
Code:
public void TestQuery()
{
string file = #"C:\Users\Michael\Downloads\7z1900-x64.msi";
// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
// Create the Windows Installer object
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
// Open the MSI database in the input file
Database database = installer.OpenDatabase(file, 0);
// Open a view on the Property table for the version property
View view = database.OpenView("SELECT * FROM `File`");
// Execute the view query
view.Execute(null);
// Get the record from the view
Record record = view.Fetch();
int i = 1;
string[] sreturns = new string[60];
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
}
First thing I see is that you're starting at 1, while (C#) arrays are 0-based.
In you screenshot I see that i is 60, so that would be the problem. Index 60 doesn't actually exist in your array, as it goes from 0 to 59.
You can add i < sreturns.Length to make sure you are in the array range.
Also, make sure you start with i = 0 and not 1.
int i = 0;
string[] sreturns = new string[60];
while (record != null && i < sreturns.Length)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
Why not using a list instead of an array?
List<string> sreturns = new List<string>();
while (record != null)
{
try
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
var result = record.get_StringData(0);
sreturns.Add(result.ToString());
}
catch (Exception e)
{
Console.WriteLine("No record...");
}
}
This way you dont need to worry about the array size - its maintainable -efficient - and if in the future the size change you don't have to worry about it.
List documentation here
What is the query with LIKE that you have tried? The following should work:
SELECT * FROM File WHERE FileName LIKE '%.exe' OR FileName LIKE '%.msi'
EDIT: On further investigation (https://learn.microsoft.com/en-us/windows/win32/msi/sql-syntax), the documentation seems to imply that the LIKE operator is not supported. But you could start off with an IS NOT NULL and do more complex filtering in the loop, like you're doing.
EDIT 2, expanding on Alex Leo's answer.
List<string> sreturns = new List<string>();
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
var result = record.get_StringData(0);
if(!string.IsNullOrWhiteSpace(result) && (result.EndsWith(".exe") || result.EndsWith(".msi")))
{
sreturns.Add(result.ToString());
}
record = view.Fetch();
}
Note that the view.Fetch() inside the while loop has been moved to the end, or you would skip the first record, as well as get another null reference when the last record has already been read, but the while loop executes one more time.

System.Data.EvaluateException HResult=0x80131920 Message=Cannot perform '=' operation on System.Int32 and System.String

public void MatchedDocumentsInFileCabinet(string MainFolder, string SubFolder, string FileName, string FilePath)
{
// Checking Main Folder is present in FileCabinet, if present retrieving MainFolderID if not Inserting MainFolderName
if (SelectedFileCabinetID == "")
{
SelectedFileCabinetID = "1";
}
int Mainfoldercount = 0;
DocSortResult getfolderdetails = objFolderManager.GetFolderDetails();
DataTable getFolderNames = new DataTable();
if (getfolderdetails.resultDS != null && getfolderdetails.resultDS.Tables[0].Rows.Count > 0)
{
// Following line is showing error
DataRow[] drResult = getfolderdetails.resultDS.Tables[0].Select("FileCabinet_ID = '" + SelectedFileCabinetID + "'" + "and" + " ParentFolderID = '" + "0" + "'" + "and" + " IsDelete = '" + "True" + "'");
if (drResult.Count() != 0)
{
getFolderNames = drResult.CopyToDataTable();
}
}
}
Without knowing getfolderdetails.resultDS.Tables[0] structure is hard to know which column is, but one of those columns is integer and your Select(filter) is telling that all the fields are string.
An example of your code debugging would show .Select("FileCabinet_ID = '4' and ParentFolderID = '0' and IsDelete = 'True' "). And the error message says one of them is not a string.
I would bet that IsDelete = 'True' probably will be boolean (bit column in SQL Server) and FileCabinet_ID or ParentFolderID or both of them are integer (and this is causing the error).
Set a breakpoint and check the datatypes of the datacolumns you are trying to filter.

Search data gridview using textbox and checkboxlist asp.net c#

I want to use textbox and checkboxlist to search data in gridview using asp.net c#. Using textbox can search the data. But for checkboxlist only can search the data when check only one checkbox. If check more than one checkbox, can't search the data. thanks a lot for helping.
the code:
c# code
protected void btnSearch_Click(object sender, EventArgs e)
{
if (cblDay.SelectedIndex != -1)
{
foreach (ListItem val in cblDay.Items)
{
if (val.Selected == true)
{
RptRateData.Day += val.Value + "";
}
}
}
RptRateData.RateAmount = txtRate.Text.Trim();
BindGrid();
}
code for class:
public string RateAmount { get; set; }
public string Day { get; set; }
internal DataSet GetRptRateSet()
{
DataSet tmpDS = new DataSet();
try
{
string strSQL = #"SELECT ComplexRateInfo.ComplexRateId,
ComplexRateDetailInfo.Day,
ComplexRateInfo.RateAmount
FROM ComplexRateInfo
LEFT JOIN ComplexRateDetailInfo ON ComplexRateInfo.ComplexRateId = ComplexRateDetailInfo.ComplexRateId ";
string whereSQL = " WHERE";
string orderBySQL = " order by Day ;";
int filterCount = 0; //to keep track of needed filter that are going to be used by the sql string
string[] sIndex = new string[2]; //to keep track of scalar variable needed by the sql, four string of sIndex because maximum filter available is 4
int indexCount = 0; //count to access sIndex members
//filter with or without day
if (_ds.Day != null && _ds.Day != "")
{
if (filterCount > 0) //query need additional filter
whereSQL = whereSQL + " AND ComplexRateDetailInfo.Day LIKE '{" + filterCount + "}'";
else //if this is the first filter
whereSQL = whereSQL + " ComplexRateDetailInfo.Day LIKE '{" + filterCount + "}'";
filterCount++;
sIndex[indexCount] = _ds.Day;
indexCount++;
}
//filter with or without rate amount
if (_ds.RateAmount != null && _ds.RateAmount != "")
{
if (filterCount > 0) //query need additional filter
whereSQL = whereSQL + " AND ComplexRateInfo.RateAmount LIKE '{" + filterCount + "}'";
else //if this is the first filter
whereSQL = whereSQL + " ComplexRateInfo.RateAmount LIKE '{" + filterCount + "}'";
filterCount++;
sIndex[indexCount] = _ds.RateAmount;
indexCount++;
}
//build complete query with no filter at all
if (filterCount == 0)
{
strSQL = strSQL + orderBySQL;
tmpDS = Db.GetDataSet(string.Format(strSQL));
}
//build complete query with 1 or more filter
else
{
strSQL = strSQL + whereSQL + orderBySQL;
tmpDS = Db.GetDataSet(string.Format(strSQL, sIndex));
}
}
catch (Exception ex)
{
throw ex;
}
return tmpDS;
}
There are two mistakes in your code.
Assigning values to RptRateData.Day from CheckBoxList.
Description: You assign selected values to object without using any separator. So For example if you have selected 1, 2, 4 days then as per your code, value of RptRateData.Day will be 124. Instead of that, it should be separated with comma as shown below:
var selectedDays = string.Empty;
foreach (ListItem val in cblDay.Items)
{
if (val.Selected == true)
{
selectedDays += "'" + val.Value + "',";
}
}
RptRateData.Day = selectedDays.TrimEnd(new char[] { ',' });
Now come to the second point which is in your SQL query which you make dynamically.
Description: In this query in WHERE clause you use Like operator for ComplexRateDetailInfo.Day. This will not work anymore. Instead of that you should use IN operator.
Note: Are you sure that your Like operator is working with curly braces ('{' and '}') and without '%' symbol ?

Get Set for a phone number

In my database, I store phone numbers like this "7279884545". One solid string with no spaces.
In my class that stores the phone number info, I have a function that will add the correct punctuation.
public static String beautifyPhoneNumber(String number, String extension)
{
String beautifulNumber = "";
if (!String.IsNullOrEmpty(number))
{
beautifulNumber = "(" + number.Substring(0, 3) + ") " +
number.Substring(3, 3) + "-" +
number.Substring(6, 4);
}
if (!String.IsNullOrEmpty(extension))
{
beautifulNumber += " x" + extension;
}
return beautifulNumber;
}
And here is how I have the variable in the class itself.
private string _PhonePrimary;
[DisplayName("Phone Primary")]
public string PhonePrimary
{
get
{
if(this._PhonePrimary != null)
{
this._PhonePrimary = beautifyPhoneNumber(this._PhonePrimary, this.Extension);
}
return this._PhonePrimary;
}
set
{
this._PhonePrimary = value;
}
}
This works fine most of the time. The numbers are outputted to the screen in a "(727) 988-4545" or "(727) 988-4545 x12" if there is an extension for that record in the database.
The problem comes when I do a HttpPost request. The model information that is inside of the post request looks like this.
_PhonePrimary = "(727) 988-4545"
PhonePrimary = "(((7) 2) -7) -"
As noted, it looks like you're calling beautifyPhoneNumber on a number you've already beautified.
Here's an implementation using regular expressions that should get you started:
public static String BeautifyPhoneNumber(string numberToBeautify)
{
//The below gives us capture groups for each
//individual piece of the number.
var regularExpression = new Regex(#"(\d{3})(\d{3})(\d{4})(x\d*)?");
//This matches a number that's already been beautified,
//so we can guard against beautifying twice.
var alreadyBeautifulExpression = new Regex(#"(\(\d{3}\)) (\d{3})-(\d{4}) ?(x\d*)?");
var beautifulNumber = string.Empty;
var separator = "-";
var space = " ";
//This prevents us from accidentally beautifying
//something more than once
//You could also guard against this in your getter using a
//IsBeautified extension, using the alreadyBeautifulExpression above
if (alreadyBeautifulExpression.IsMatch(numberToBeautify))
{
return numberToBeautify;
}
//Trying to protect against invalid input... May be insufficient,
//Or unnecessary
if (string.IsNullOrEmpty(numberToBeautify)
|| regularExpression.Matches(numberToBeautify).Count <= 0)
{
return beautifulNumber;
}
GroupCollection groups = regularExpression.Matches(
numberToBeautify)[0].Groups;
//More protection against invalid input
if (groups.Count < 3)
{
return beautifulNumber;
}
//Given "7689131234",
beautifulNumber += "(" + groups[1] + ")" + space; //gives us "(768) "
beautifulNumber += groups[2] + separator; //gives us "(768) 913-"
beautifulNumber += groups[3]; //gives us "(768) 913-1234"
//If we have an extension, we add it.
if (groups[4] != null)
{
beautifulNumber += space + groups[4];
}
return beautifulNumber;
}
Given inputs of:
7279884545
7279884545x12
(727) 988-4545
This returns:
(727) 988-4545
(727) 988-4545 x12
(727) 988-4545

Weird issue in c# related to DataSet

I'm currently working on a program that converts japanese characters to english characters and the other way around.
It's not working much though, For the last few days I've been trying everything to try and get it to work, it's probably some small dumb problem but I just can't find it. I'm pretty new to all this so any help is appreciated.
Now the problem is that it only wants to convert Romaji characters, however if change some code, more specifically if I change the following from "if" to else if, then it converts hiragana and katakana but NOT romaji..
string fromtype = "";
// Determines what type the character is currently
// && fromtype == "" added to avoid weird unexplainable errors...
if (CharacterTable.Select("Romaji = '" + character + "'") != null && fromtype == "")
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Katakana";
}
I've even tried removing this function that tries to automatically find what type the character is and do it with radiobuttons so that the user has to select it, but somehow it seems to do pretty much the same thing... So I'm totally confused at this point, any help is very much welcome.
Here is the full code:
public string CheckCharacter(string character, int RequestedCharType)
{
// RequestedCharType
// 1 = Romaji
// 2 = Hiragana
// 3 = Katakana
//-- Instantiate the data set and table
DataSet CharacterDatabase = new DataSet();
DataTable CharacterTable = CharacterDatabase.Tables.Add();
//-- Add columns to the data table
CharacterTable.Columns.Add("Romaji", typeof(string));
CharacterTable.Columns.Add("Hiragana", typeof(string));
CharacterTable.Columns.Add("Katakana", typeof(string));
//-- Add rows to the data table
CharacterTable.Rows.Add("a", "あ", "ア");
CharacterTable.Rows.Add("i", "い", "イ");
// Sets fromtype to the type the character(s) currently is/are
string fromtype = "";
// Determines what type the character is currently
// && fromtype == "" added to avoid weird unexplainable errors...
if (CharacterTable.Select("Romaji = '" + character + "'") != null && fromtype == "")
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Katakana";
}
// generates a new variable to store the return in
DataRow[] filteredRows = CharacterTable.Select(fromtype + " = '" + character + "'");
// Return the converted character in the requested type
foreach (DataRow row in filteredRows)
{
if (RequestedCharType == 1)
{
return row["Romaji"].ToString();
}
if (RequestedCharType == 2)
{
return row["Hiragana"].ToString();
}
if (RequestedCharType == 3)
{
return row["Katakana"].ToString();
}
}
// if it couldn't find the character, return the original character
return character;
}
Your problem is in your misunderstanding of how Select works. Select does not return null when there are no matches so your first if is always true. Instead you need to check whether there were any results which you can do with Enumerable.Any() (add using System.Linq):
if (CharacterTable.Select("Romaji = '" + character + "'").Any())
{
fromtype = "Romaji";
}
else ...
Alternatively you can check the array length:
if (CharacterTable.Select("Romaji = '" + character + "'").Length > 0)
{
fromtype = "Romaji";
}
else ...
I'm not sure what the fromType == "" bit is all about this is surely not needed.
Considering creating an enum type for your char types.
This method can be made static.
Consider using a switch statement instead of if (RequestedCharType == 1)
&c.

Categories

Resources