为什么当我的 CSV 包含 5 列时,我的变量 lat 返回数组超出界限?



我尝试使用Java处理CVS文件。我完成了前 3 列所需的操作,但 dataContent[3] 返回错误。 我不明白为什么我的 CSV 文件在这里可用,是 5 列。知道吗??

while ((lsLigne = br.readLine()) != null) {
dataContent = lsLigne.split(";");
for (i = 0; i < dataContent.length; i++) {
cities = dataContent[0];
insee = dataContent[1];
lng = dataContent[2];
lat = dataContent[3]; // line causing problems         
}

if (cities.isEmpty()) {
System.out.println("Attention nom de commune manquant");
} else if (!cities.matches(motifLettersOnly)) {
System.out.println("Attention nom de ville erroné : " + cities);
} else if (insee.isEmpty()){
System.out.println("Attention l'Insee est manquant");            
} else if(!insee.matches(motifNumbersOnly)){
System.out.println("Attention Insee erronée : " + insee);         
} else if(lng.isEmpty()){
System.out.println("Attention la longitude est manquante");
} else if(!lng.matches(motifNumbersOnly)){
System.out.println("Attention longitude erronée " + lng);
}
}

nom;insee;lng;lat;
OZAN;1284;4.91667;46.3833;
CORMORANCHE-SUR-SAONE;1123;4.83333;46.2333;
PLAGNE;1298;5.73333;46.1833;
TOSSIAT;1422;5.31667;46.1333;
POUILLAT;1309;5.43333;46.3333;
TORCIEU;;5.4;45.9167;
REPLONGES;1320;4.88333;Hello;
11111;1119;5.58333;46.0333;Champ sup
PERON;1288;5.93333;46.2;
RELEVANT;Hello;4.95;46.0833;
CHAVEYRIAT;1096;5.06667;46.1833;
;1431;5.35;45.9167;
MAILLAT;1228;;46.1333;
FARAMANS;1156;5.11667;;
BEON;1039;5.75;45.8333;
SAINT-BERNARD;1339;4.73723;lol;
ROSSILLON;1329;zaz;45.8333;

此循环

for (i = 0; i < dataContent.length; i++)

完全没用,你可以摆脱它。

我看了一下你的 CSV,你在法拉曼斯列中没有 lat 的值,这可能就是你得到一个越界异常的原因,因为你正在迭代每一行

while ((lsLigne = br.readLine()) != null)

您可以像这样避免越界异常,如果值在 csv 中不可用,则将其留空。

while ((lsLigne = br.readLine()) != null) {
dataContent = lsLigne.split(";");
if (dataContent.length > 0) {
cities = dataContent[0];
if (dataContent.length > 1)
insee = dataContent[1];
if (dataContent.length > 2)
lng = dataContent[2];
if (dataContent.length > 3)
lat = dataContent[3]; // line no longer causing problems         
if (cities == null || cities.isEmpty()) {
System.out.println("Attention nom de commune manquant");
} else if (!cities.matches(motifLettersOnly)) {
System.out.println("Attention nom de ville erroné : " + cities);
} else if (insee == null || insee.isEmpty()){
System.out.println("Attention l'Insee est manquant");            
} else if(!insee.matches(motifNumbersOnly)){
System.out.println("Attention Insee erronée : " + insee);         
} else if(lng == null || lng.isEmpty()){
System.out.println("Attention la longitude est manquante");
} else if(!lng.matches(motifNumbersOnly)){
System.out.println("Attention longitude erronée " + lng);
}
}
}

肯定还有更好的方法来处理这个逻辑,所以你可以从这里开始。

如果你真的想使用它 for loop,你也可以做这样的事情。

for (int i = 0; i < dataContent.length; i++) {
switch(i) {
case 0: cities = dataContent[i]; break;
case 1: insee = dataContent[i]; break;
case 2: lng = dataContent[i]; break;
case 3: lat = dataContent[i]; break;
}
}

如上面的评论中所述,代码的许多方面可以/应该改进,但我将仅将这个答案集中在数据验证上。 在使用之前,应检查/验证程序数据的任何外部内容。external我的意思是不是由程序直接创建/管理的任何数据。理想情况下,在接收数据时完成此操作,因为这会限制可能受无效数据影响的代码深度。为了使验证有效/可能,重要的是输入数据格式由应用程序的所有用户指定和同意(简而言之,应该知道如何使用任何其他规则/例外格式化数据(。

事先知道这些信息后,可以构建解析器来读取所有有效的输入数据并处理任何错误。

回到您的示例,我假设有效的输入行(String(是:

  • 由 4 个元素(列(组成,由;分隔
  • 第一个元素是cities- 一个由motifLettersOnly组成的非空String
  • 第二个元素是insee- 一个由motifLettersOnly组成的非空String
  • 第三个元素是lng- 一个由motifNumbersOnly组成的非空String

其他任何内容都将被视为无效数据,应作为错误处理(在这种情况下 - 将消息记录到System.out(。

这是代码的略微修改版本(同样,它不是一个完整的解析器,因为它只是验证数据(:

while ((lsLigne = br.readLine()) != null) {
String[] dataContent = lsLigne.split(";");
if (dataContent.length != 4) {
System.out.println("Invalid input data: " + lsLigne);
continue; // Not 4 elements --> the whole line is invalid and is skipped
}
String cities = dataContent[0];
String insee = dataContent[1];
String lng = dataContent[2];
String lat = dataContent[3];
// cities validation
if (cities.isEmpty()) {
System.out.println("Attention nom de commune manquant");
} else if (!cities.matches(motifLettersOnly)) {
System.out.println("Attention nom de ville erroné : " + cities);
}
// insee validation
if (insee.isEmpty()) {
System.out.println("Attention l'Insee est manquant");
} else if (!insee.matches(motifNumbersOnly)) {
System.out.println("Attention Insee erronée : " + insee);
}
// lng validation
if (lng.isEmpty()) {
System.out.println("Attention la longitude est manquante");
} else if (!lng.matches(motifNumbersOnly)) {
System.out.println("Attention longitude erronée " + lng);
}
}

请注意,首先检查整行的有效元素数 - 这确保了 3 个或更少元素没有IndexOutOfBounds异常,但也确保元素不超过 4 个(例如,如果有人错误地删除了文件中的行尾,连接了两条数据行(。

之后,每个元素(城市、insee、lng 等(验证都是在自己身上完成的 - 在您的代码中,空的cities错误会阻止inseelng的验证,这通常不是您想要的(在线上所有数据错误的报告(。

最新更新