【问题标题】:Errors in declaration when trying to parse a csv file尝试解析 csv 文件时出现声明错误
【发布时间】:2016-07-07 04:54:39
【问题描述】:

我正在尝试解析格式如下的 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 的那一行带来了同样的“未初始化值”错误,尽管我这样做了。

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

【问题讨论】:

  • 第 22 行是什么?输入的第 10 行是什么?
  • N° 107 9 de Julio;alberdi juan bautista 942;4724473\n N° 1078 John F. Kennedy;grandoli 4800;4729682\n N° 1080 Gabriela Mistral;san lorenzo 8154;4727581\n
  • 输入是这样的......而且这些是在上层代码中引起麻烦的行 ($word) = split(/\s/,$fields[1]); if (($word ne 'SAN')&&($word ne 'LA')&&($word ne 'EL')) 这些行产生我发布的错误
  • 请注意,我在输入示例中写了\n,因为我在编辑评论时无法插入换行符
  • John Kennedy 似乎没有$fields[1],因此出现警告(这不是错误)。

标签: string perl parsing csv text-parsing


【解决方案1】:

您提供的错误消息以:line 22, &lt;$in&gt; line 10. 结尾,但您的问题未显示数据的第 10 行 ($in),需要在此答案中进行一些推测 - 但是,我想说第二个字段 @ in.txt 的第 10 行的 987654323@ 为空。

因此,这行:($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 - 所以你可能想告诉我不要管我自己的事。 :-)

【讨论】:

  • 正如您和戴夫指出的那样,由于输入文件上的空行而出现警告...我知道您首先输入了答案,但我认为戴夫一个会更有启发性对于进入这个问题的新手,所以我将选择他的答案作为解决方案。我希望我可以选择两者,因为你们都说对了,但我不能。
  • 你的动机是帮助新手,你已经承认我的回答首先 - 我很高兴。
【解决方案2】:

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

使用未初始化的值

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

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

(W uninitialized) 使用了一个未定义的值,就好像它已经被使用了一样 定义。它被解释为“”或 0,但可能是一个错误。 要抑制此警告,请为您的变量分配一个定义的值。

为了帮助您找出未定义的内容,perl 会尝试告诉您 未定义的变量(如果有)的名称。在某些情况下 它不能这样做,所以它还会告诉你你使用了什么操作 未定义的值。但是请注意,perl 优化了您的程序 并且警告中显示的操作不一定会出现 从字面上看,在您的程序中。例如,“that $foo”通常是 优化为 "that" 。 $foo,警告将指向 连接 (.) 运算符,即使没有 .在 你的程序。

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

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

【讨论】:

  • 是的,这是警告原因,输入文本文件中有一个空行。谢谢。
猜你喜欢
  • 2014-09-09
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
相关资源
最近更新 更多