2014-09-14 3 views
0

필자는 Perl에서 파일을 조작하는 것이 비교적 새로운 경험이 있습니다. 이 코드가 내 텍스트 파일에 아무 것도 쓰지 않는 것이 무엇이 잘못된지 나는 모른다. 데이터 구조의 내용을 인쇄하는 다른 함수가 있고 데이터가 거기에 있기 때문에 데이터 구조와 관련이 있다고 생각하지 않습니다. 단지 파일에 기록되지 않습니다. 내가 놓친 게 있니? 소스 서식 개선을 원하지만이 함수가 왜 내 파일에 Perl로 아무 것도 쓰지 않습니까?

sub saveFile { 
    open(my $out, ">", "inputs.txt"); 
    for ($i = 0; $i < $#students; $i++) { 
     print $out $students[$i]->{"name"}; 
     print $out $students[$i]->{"studNum"}; 
     print $out $students[$i]->{"cNum"}; 
     print $out $students[$i]->{"emailAdd"}; 
     print $out $students[$i]->{"gwa"}; 
     print $out $students[$i]->{"subjNum"}; 
     for ($j = 0; $j < $students[$i]->{"subjNum"}; $j++) { 
      print $out $students[$i]->{"subj"}->[$j]->{"courseNum"}; 
      print $out $students[$i]->{"subj"}->[$j]->{"courseUnt"}; 
      print $out $students[$i]->{"subj"}->[$j]->{"courseGrd"}; 
     } 
    } 
    close $out; 
    print "FILE SAVED.\n"; 
} 
+2

'엄격한 사용; 경고를 사용한다; 그렇지 않은 경우 추가하고 경고를 수정하십시오. 또한 전역 변수를 피하고 함수의 인수로 전달해야합니다. – TLP

+0

해시 참조를 사용할 때'$ students [$ i] -> { "subj"} -> [$ j] -> { "courseNum"}'을 입력하는 대신 한 개의 화살표 만 사용하면됩니다 :'$ students [ $ i] -> { "subj"} [$ j] { "courseNum"}'. –

+1

항상'open'의 리턴 코드를 확인하고 적절한 조치를 취하십시오. '내 $ out ',' ','inputs.txt '를 열거 나 죽습니다. "inputs.txt를 열 수 없습니다 : $! \ n";' –

답변

2

, 당신의 기술은 기본적으로 옳다 : 여기

는 코드입니다. 그러나 코드에서이 작은 오류가 있습니다 :
$i<$#students 

이 그것을 $i<=$#students 또는 $i<@students 중 하나를합니다. 그것은 당신의 문제를 해결해야합니다. 그런데

, 당신은 형식 (및 관용구)를 개선하고자하는 경우,이 대안은 당신에게 몇 가지 아이디어를 줄 수 있습니다 당신은 당신이 당신의 루프 조건에서 <=을 사용해야 <을 사용했다

sub saveFile { 

    open(my $out, '>', 'inputs.txt'); 

    for (my $i = 0; $i <= $#students; ++$i) { 

     print $out $students[$i]{name}; 
     print $out $students[$i]{studNum}; 
     print $out $students[$i]{cNum}; 
     print $out $students[$i]{emailAdd}; 
     print $out $students[$i]{gwa}; 
     print $out $students[$i]{subjNum}; 

     for (my $j = 0; $j < $students[$i]{subjNum}; ++$j) { 
      print $out $students[$i]{subj}[$j]{courseNum}; 
      print $out $students[$i]{subj}[$j]{courseUnt}; 
      print $out $students[$i]{subj}[$j]{courseGrd}; 
     } 

    } 

    close $out; 
    print "FILE SAVED.\n"; 

} 
+1

아. 못 봤어. 방금 언급 한 변수가 배열의 마지막 요소를 추적하고 그 다음 요소는 추적하지 않습니다. 고맙습니다! – ejandra

+0

프로토 타입에 빈 인자 목록을 사용하는 것은 중복되고 사물을 복잡하게 만듭니다. 'sub saveFile {}'은 당신이 사용해야하는 것입니다. – TLP

+1

@thb OP는 해시 레프에서 여분의 화살표를 제거 할 수 있으며 간단한'for (@ $ students) '와'for (@ {$ students [$ i]})'를 삭제할 수 있습니다. –

4

. 이 때문에

for ($i = 0; $i < $#students; $i++) { 
#    ^^-- here 

는, 마지막 인덱스는 인쇄되지 않습니다, 나는 당신이 단지 하나 개의 레코드를 사용하여 테스트하는 가정합니다.

이 방법은 배열을 반복하는 방법이 아닙니다. 당신이 뭔가 다른 배열 인덱스를 필요로하지 않는 한 - - 훨씬 선호하는 방법은 실제 요소를 반복 할 수 있습니다 :

for my $student (@students) { 
    print $student->{"name"}; 
    ... 
} 

각 요소 여기에 상당히 귀하의 입력을 단순화하고 만들 것입니다 해시 심판을하게 될 더 읽기 쉬운 코드.

print @{$student}{qw(name studNum cNum emailAdd)}; 

주 당신이 뭔가에 다양한 값을 구분 할 수 있습니다 :

print join ",", @{$student}{qw(name studNum cNum emailAdd)}; 

당신은 대신 하나 하나를 인쇄하는, 당신의 기록을 인쇄 할 해시 조각을 사용할 수 있습니다

마지막으로, 주석에서 말한 것처럼 전역 변수를 사용하지 않아야합니다. 대신 배열을 함수에 전달하십시오. 내 모든 조언과 결합, 나는이 함께했다 : 나는 멀리 배열의 크기를 얻을 간단하다으로, 중복되는 subjNum 키와 함께 수행 한

saveFile(\@students); 

...; 
use feature 'say'; # required for say() 

sub saveFile { 
    my $aref = shift; 
    for my $student (@$aref) { 
     say join ",", @{$student}{qw(name studNum cNum emailAdd gwa subjNum)}; 
     for my $subj (@{ $student->{"subj"} }) { 
      say join ",", @{$subj}{qw(courseNum courseUnt courseGrd)}; 
     } 
    } 
} 

참고.

관련 문제