C# 将子字符串转换为整数时出现奇怪的问题
我有一个奇怪的问题。很明显,由于某种奇怪的原因,我得到的字符串不能被转换成Int32。我尝试这样做时得到的错误消息是“输入字符串格式不正确”。因此,我也无法将这些值插入数据库 这是密码C# 将子字符串转换为整数时出现奇怪的问题,c#,sqlite,casting,substring,int32,C#,Sqlite,Casting,Substring,Int32,我有一个奇怪的问题。很明显,由于某种奇怪的原因,我得到的字符串不能被转换成Int32。我尝试这样做时得到的错误消息是“输入字符串格式不正确”。因此,我也无法将这些值插入数据库 这是密码 string width = GetMetadata(filename, 162); //returns "1280 pixels" string height = GetMetadata(filename, 164); //returns "700 pixels" width = width.Substring
string width = GetMetadata(filename, 162); //returns "1280 pixels"
string height = GetMetadata(filename, 164); //returns "700 pixels"
width = width.Substring(0, width.IndexOf(' ')); //returns "1280"
height = height.Substring(0, height.IndexOf(' ')); //returns "700"
//test: "System.Convert.ToInt32(width)" will fail, giving error "input string was not in correct format"
//doing the above on "width" yields the same result
//fails, giving error "no such column: 1280" (underlying database is sqlite)
Database.NonQuery("INSERT INTO image VALUES (" + fileid + ", " + width + ", " + height + ")");
出于所有正常原因(主要是避免将数据转换留给数据库,以及防止SQL注入攻击),我建议您对C#中的数字执行解析,然后使用a与SQLite对话 在这种情况下,这将使调试更加容易-要么.NET也无法解析字符串(在这种情况下,您的数据可能会有问题),要么它可以工作,并且您不必担心数据库执行了什么转换 编辑:我刚刚看到你的评论说,
Convert.ToInt32
也失败了。这非常清楚地表明,是数据造成了问题
我希望您的代码如下所示:
string widthText = GetMetadata(filename, 162);
string heightText = GetMetadata(filename, 164);
widthText = width.Substring(0, width.IndexOf(' ')).Trim();
heightText = height.Substring(0, height.IndexOf(' ')).Trim();
int width = int.Parse(widthText, CulutureInfo.InvariantCulture);
int height = int.Parse(widthText, CulutureInfo.InvariantCulture);
using (SQLiteCommand cmd = Database.CreateCommand())
{
cmd.CommandText = "INSERT INTO image VALUES (?, ?, ?)";
cmd.Parameters.Add(fileid);
cmd.Parameters.Add(width);
cmd.Parameters.Add(height);
cmd.ExecuteNonQuery();
}
请注意,
Trim
调用将删除任何前导空格,这似乎是问题的原因。出于所有正常原因-主要是避免将数据转换留在数据库中,并防止SQL注入攻击-我建议您对C#中的数字执行解析,然后使用a与SQLite对话
在这种情况下,这将使调试更加容易-要么.NET也无法解析字符串(在这种情况下,您的数据可能会有问题),要么它可以工作,并且您不必担心数据库执行了什么转换
编辑:我刚刚看到你的评论说,Convert.ToInt32
也失败了。这非常清楚地表明,是数据造成了问题
我希望您的代码如下所示:
string widthText = GetMetadata(filename, 162);
string heightText = GetMetadata(filename, 164);
widthText = width.Substring(0, width.IndexOf(' ')).Trim();
heightText = height.Substring(0, height.IndexOf(' ')).Trim();
int width = int.Parse(widthText, CulutureInfo.InvariantCulture);
int height = int.Parse(widthText, CulutureInfo.InvariantCulture);
using (SQLiteCommand cmd = Database.CreateCommand())
{
cmd.CommandText = "INSERT INTO image VALUES (?, ?, ?)";
cmd.Parameters.Add(fileid);
cmd.Parameters.Add(width);
cmd.Parameters.Add(height);
cmd.ExecuteNonQuery();
}
请注意,
Trim
调用将删除任何前导空格,这似乎是问题的原因。字符串变量width
和height
中可能有一些多余的空格。在将字符串转换为整数之前,对字符串调用Trim()
方法:
width = width.Trim();
height = height.Trim();
希望这有帮助。让我们知道。字符串变量
width
和height
中可能有一些零散的空格。在将字符串转换为整数之前,对字符串调用Trim()
方法:
width = width.Trim();
height = height.Trim();
希望这有帮助。让我们知道。您已经在其中设置了一个断点,并绝对验证了
GetMetadata()
返回的值是否符合预期?没有多余的空间?没有制表符或其他不正确的空格?因为有了“1280像素”和“700像素”的值,代码运行得很好。@Carson:是的,注释中的值正是我得到的。如果不是这样,我会仔细检查并发回。首先,在处理数据库时最好使用参数。开发机器上的当前区域性是什么?当您指定width=“1280像素”时,它可以正常工作。我同意Carson63000-仔细检查GetMetadata的结果。将起始索引设置为1似乎解决了这个问题。那里一定有空白或其他我以前没有看到的字符。您已经在其中放置了一个断点,并绝对验证了GetMetadata()
返回的值是否符合预期?没有多余的空间?没有制表符或其他不正确的空格?因为有了“1280像素”和“700像素”的值,代码运行得很好。@Carson:是的,注释中的值正是我得到的。如果不是这样,我会仔细检查并发回。首先,在处理数据库时最好使用参数。开发机器上的当前区域性是什么?当您指定width=“1280像素”时,它可以正常工作。我同意Carson63000-仔细检查GetMetadata的结果。将起始索引设置为1似乎解决了这个问题。那里一定有空白或其他我以前没见过的字符。问题已经解决了,所以我在这里开始切线。除了防止注入攻击之外,使用参数化查询而不是普通查询还有什么好处吗?目前,我只使用需要将用户输入插入数据库的参数化查询。@rafale:它将代码(SQL)与数据(值)分开。这意味着您可以真正清晰地从代码中单独查看数据。。。以及避免在代码中已经获得非字符串形式的数据时在数据库中进行转换。在传递日期之类的东西时,这一点尤其重要,因为显然有几种不同的表示日期的格式。我认为在不处理用户输入时使用非参数化查询是不好的做法。然后,每次查看查询时,你都必须问自己,“嘿,这是非参数化的。我确定即使在将来也不会看到用户输入吗?”问题已经解决了,所以我在这里开始正切。除了防止注入攻击之外,使用参数化查询而不是普通查询还有什么好处吗?目前,我只使用需要将用户输入插入数据库的参数化查询。@rafale:它将代码(SQL)与数据(值)分开。这意味着您可以真正清晰地从代码中单独查看数据。。。以及避免在代码中已经获得非字符串形式的数据时在数据库中进行转换。在传递日期之类的东西时,这一点尤其重要,因为显然有几种不同的表示日期的格式。我认为在不处理用户输入时使用非参数化查询是不好的做法。然后,每次查看查询时,您都必须问自己,“嘿,这是非参数化的。我确定这不会发生吗