尝试解析csv文件时声明中的错误

时间:2016-03-20 19:07:43

标签: string perl parsing csv text-parsing

我正在尝试解析格式如下的CSV文件:

    dog cats,yellow blue tomorrow,12445
    birds,window bank door,-novalue-
    birds,window door,5553
    aspirin man,red,567

(没有写入-novalue-的值)

use strict;
use warnings;


my $filename = 'in.txt';
my $filename2 = 'out.txt';

open(my $in, '<:encoding(UTF-8)', $filename)
or die "Could not open file '$filename' $!";

my $word = "";

while (my $row = <$in>) {
    chomp $row;

    my @fields = split(/,/,$row);

    #Save the first word of the second column
    ($word) = split(/\s/,$fields[1]);

    if ($word eq 'importartWord')
    {
        printf $out "$fields[0]".';'."$word".';'."$fields[2]";
    }   
    else #keep as it was
    {
        printf $out "$fields[0]".';'."$fields[1]".';'."$fields[2]";
    }
Use of uninitialized value $word in string ne at prueba7.pl line 22, <$in> line 10.

无论我在哪里定义$ word,我都无法停止接收该错误并且无法理解原因。我想我已正确初始化$ word。我非常感谢你的帮助。

如果你打算建议使用Text :: CSV发布一个工作代码示例,因为我还没有能够将它应用于我在这里解释的建议。这就是我最终编写上述代码的原因。

PD:    因为我知道您将使用Text :: CSV请求我以前的代码,所以它是:

#!/usr/bin/perl
use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new({ sep_char => ';', binary => 1 }) or 
                    die "Cannot use CSV: ".Text::CSV->error_diag ();


#directorio donde esta esc_prim2.csv
my $file = 'C:\Users\Sergio\Desktop\GIS\perl\esc_prim2.csv';
my $sal = 'C:\Users\Sergio\Desktop\GIS\perl\esc_prim3.csv';


open my $data, "<:encoding(utf8)", "$file" or die "$file: $!";
open my $out, ">:encoding(utf8)", "$sal" or die "$sal: $!";

$csv->eol ("\r\n");


#initializing variables
my $row = "";
my $word = "";
my $validar = 0;
my $line1 = "";
my @mwords = [""];#Just a try to initialize mwords... doesn't work, error keeps showing


#save the first line with field names on the other file
$line1 = <$data>;
$csv->parse($line1);
my @fields = $csv->fields();
$csv->print($out,[$fields[0], $fields[1], $fields[2]]);



while ($row = <$data>) {

    if ($csv->parse($row)) {
        @fields = $csv->fields();

        #save first word of the field's second element 
        @mwords = split (/\s/, $fields[1]);

        #keep the first one
        $word = $mwords[0];

        printf($mwords[0]);

        #if that word is not one of SAN, EL y LA... writes a line in the new file with the updated second field.
        $validar = ($word ne 'SAN') && ($word ne 'EL') && ($word ne 'LA');
        if ($validar)
        {
            $csv->print($out,[$fields[0], $word, $fields[2]]);
        }
        else { #Saves the line in the new file as it was in the old one.
            $csv->print($out,[$fields[0], $fields[1], $fields[2]]);
        }


    } else {#error procesing row
        warn "La row no se ha podido procesar\n";
    }
}

close $data or die "$file: $!";
close $out or die "$sal: $!";

此处声明$ validar的行带来了&#34;未初始化值&#34;的相同错误。虽然我做到了。

我也试过了 push @rows,$ row; 方法,但我真的不知道如何处理$ rows [$ i],因为它们是对数组(指针)的引用而且我知道它们不能作为变量来操作......无法找到关于如何使用它们的工作示例。

2 个答案:

答案 0 :(得分:1)

您提供的错误消息以line 22, <$in> line 10.结尾,但您的问题并未显示数据的第10行($in),需要在此答案中进行一些推测 - 但是,我&#39; d说$field[1]第10行的第二个字段in.txt为空。

因此,此行:($word) = split(/\s/,$fields[1]);导致$word未定义。因此,后者的一些用法 - 无论是ne运算符(如消息中所示)还是其他任何内容都会产生错误。

顺便说一句,在字符串中插入变量本身就没有什么意义;而不是"$fields[0]",而是$fields[0],除非您要在其中添加其他内容,例如"$fields[0];"。您可能需要考虑更换

printf $out "$fields[0]".';'."$word".';'."$fields[2]"; 

printf $out $fields[0] . ';' . $word . ';' . $fields[2];

printf $out "$fields[0];$word;$fields[2]"; 

当然,TMTOWTDI - 所以你可能想告诉我要关注自己的事业。 : - )

答案 1 :(得分:1)

我认为您误解了错误。变量的声明不是问题,而是你将变量放入变量的数据。

  

使用未初始化的值

这意味着您正在尝试使用未定义的值(未声明)。这意味着您正在使用一个您没有给出值的变量。

通过在代码中添加use diagnostics,您可以获得有关警告的更多详细信息(并且它是警告,而不是错误)。你会得到这样的东西:

  

(W未初始化)使用未定义的值,就像它已经存在一样       定义。它被解释为&#34;&#34;或者是0,但也许这是一个错误。       要禁止此警告,请为变量分配定义的值。

     

为了帮助您弄清楚未定义的内容,perl将尝试告诉您       未定义的变量(如果有)的名称。在某些情况下       它不能这样做,所以它也告诉你你使用了什么操作       未定义的值。但请注意,perl会优化您的程序       并且不一定会出现警告中显示的操作       字面上在你的程序中。例如,&#34;那个$ foo&#34;通常是       优化成&#34;那&#34; 。 $ foo,警告将参考       连接(。)运算符,即使没有。在       你的计划。

因此,当您填充$word时,它没有获得值。据推测,这是因为输入文件中的某些行在那里有空记录。

我无法知道这是否是您的计划的有效输入,因此我无法就如何解决此问题提供任何有用的建议。