2012-03-20 35 views
0

我剛剛接觸編程和計算器,並決定從學習目標c開始。令牌化和解析文本文件(編輯決策列表ASCII文本文件)目標C

在深處,我知道。

我被困在試圖找出解析edl文件的最佳方法。 它基本上是一個不超過100KB的ASCII文本文件。 下面是一個典型cmx3600 EDL的結構:

TITLE: EP1 FINAL.EDL SECTION2 
FCM: NON-DROP FRAME 
001 A199_C00 V  C  20:38:24:15 20:38:26:04 10:30:00:02 10:30:01:16 
* SOURCE FILE: A199_C008_0915AH_001 
002 A199_C00 V  C  20:34:48:17 20:34:51:23 10:30:01:16 10:30:04:22 
* SOURCE FILE: A199_C007_0915VE_001 

我試圖找出解析或掃描每個元素爲字段/陣列即最好的辦法,

editNum = 001 
tapeName = A199_C00 
channel = V 
Operation = C 
sourceIn = 20:38:24:15 
sourceOut = 20:38:26:04 
recIn = 10:30:00:02 
recOut = 10:30:01:16 
sourceFile = A199_C008_0915AH_001 

這是我的代碼到目前爲止:

-(IBAction)importEdl:(id)sender {  

    //defines an Array of allowed file types with file extension ".EDL and .edl" 

    NSOpenPanel *myPanel = [NSOpenPanel openPanel]; 
    NSArray *fileTypes = [NSArray arrayWithObjects:@"EDL", @"edl", nil]; 
    myPanel.allowedFileTypes = fileTypes; 
    myPanel.allowsMultipleSelection = NO; 

    if ([myPanel runModal] == NSOKButton) 
    {    

    NSString *theFilePath = [myPanel filename]; 
    NSString *psEdlFile = [NSString stringWithContentsOfFile:theFilePath encoding:NSASCIIStringEncoding error:NULL]; 
     // Reads the file as one string. EDL's are simple ASCII text files of roughly 50KB. 

    NSArray *psEdlLines = [psEdlFile componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 
     // Separates the data into lines. 

    if([psEdlLines count] == 0) 
    { 
     NSLog(@"Error!");         
    } //prints error if EDL file has no events. 


    NSUInteger count; 
    int i; 
    for (i = 0, count = [psEdlLines count]; i < count; i = i + 1) 
    { 
     NSString *lineStrings = [psEdlLines objectAtIndex:i]; 
     NSLog(@"Line %d is %@",i+1,lineStrings); 

    //NSArray *linesEnum = [psEdlLines objectAtIndex:i]; 
     //this creates an array of lines 

    //NSLog(@"index is: %d %@",i, linesEnum); 
    } 

    }     

} 

@end 

的輸出是:

2012-03-20 15:22:08.956 TestProgram[412:903] Line 1 is TITLE: EP1 FINAL.EDL SECTION2 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 2 is FCM: NON-DROP FRAME 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 3 is 001 A199_C00 V  C  20:38:24:15 20:38:26:04 10:30:00:02 10:30:01:16 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 4 is * SOURCE FILE: A199_C008_0915AH_001 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 5 is 002 A199_C00 V  C  20:34:48:17 20:34:51:23 10:30:01:16 10:30:04:22 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 6 is * SOURCE FILE: A199_C007_0915VE_001 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 7 is 003 A199_C00 V  C  20:42:32:01 20:42:35:19 10:30:04:22 10:30:08:15 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 8 is * SOURCE FILE: A199_C009_0915RX_001 
2012-03-20 15:22:08.957 TestProgram[412:903] Line 9 is 
2012-03-20 15:22:08.958 TestProgram[412:903] Line 10 is 

我還沒有走得很遠,你可以看到。 任何想法將不勝感激。 在此先感謝, 皮特。

+0

如果你正在做解析,路要走的是BNF文法。構建一個並使用它將是一個非常好的學習練習。 – 2012-03-20 17:16:45

+0

看看[ParseKit](http://www.parsekit.com/)。 – 2012-03-20 17:30:25

+0

或者'NSScanner',如果你是Cocoa的新手,並且希望能夠使用本地框架。 – FluffulousChimp 2012-03-20 18:57:38

回答

0

更多進展。

if ([lineScanner scanInt:&eventNum]) 
    { 
     // parse the event into fields 

     // does not work if edl contains dissolve or wipe 
     // need to automatically convert dissolves into cuts 

     NSString *editNum; 
     NSString *reelName; 
     NSString *channels; 
     NSString *operation; 
     //NSString *opDuration; 
     NSString *sourceInTime; 
     NSString *sourceOutTime; 
     NSString *destInTime; 
     NSString *destOutTime; 

     NSScanner *elementScanner = [NSScanner scannerWithString:line]; 

     //NSString *token = [NSString string]; 
     NSCharacterSet *divider = [NSCharacterSet whitespaceCharacterSet]; 

     [elementScanner scanUpToCharactersFromSet:divider intoString:&editNum]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&reelName]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&channels]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&operation]; 
     //[elementScanner scanUpToCharactersFromSet:divider intoString:&opDuration]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&sourceInTime]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&sourceOutTime]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&destInTime]; 
     [elementScanner scanUpToCharactersFromSet:divider intoString:&destOutTime]; 


     NSLog(@"Event\tReelName\tChannels\tOperation\tSource In\tSource Out\tDest In\t\tDest Out"); 
     NSLog(@"%@\t%@\t%@\t\t\t%@\t\t\t%@\t%@\t%@\t%@", 
       editNum, reelName, channels, operation, /*opDuration,*/ sourceInTime, sourceOutTime, destInTime,destOutTime); 

    } 

輸出以下內容。

2012-03-29 15:54:15.489 TestProgram[2414:903] Scanner:Title = EP1 FINAL.EDL SECTION2 
2012-03-29 15:54:15.489 TestProgram[2414:903] Event ReelName Channels Operation Source In Source Out Dest In  Dest Out 
2012-03-29 15:54:15.489 TestProgram[2414:903] 001 A180_C00 V   C   20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23 
2012-03-29 15:54:15.489 TestProgram[2414:903] Comment for event 001 * SOURCE FILE: A180_C001_09138L_001 
2012-03-29 15:54:15.489 TestProgram[2414:903] Event ReelName Channels Operation Source In Source Out Dest In  Dest Out 
2012-03-29 15:54:15.490 TestProgram[2414:903] 002 A181_C01 V   C   22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04 
2012-03-29 15:54:15.490 TestProgram[2414:903] Comment for event 002 * SOURCE FILE: A181_C010_0913EA_001 
2012-03-29 15:54:15.490 TestProgram[2414:903] Event ReelName Channels Operation Source In Source Out Dest In  Dest Out 
2012-03-29 15:54:15.490 TestProgram[2414:903] 003 A181_C01 V   C   22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09 
2012-03-29 15:54:15.490 TestProgram[2414:903] Effect for event  003 M2 A181_C01  000.0    22:10:05:09 
2012-03-29 15:54:15.491 TestProgram[2414:903] Comment for event 003 * * FREEZE FRAME 
2012-03-29 15:54:15.491 TestProgram[2414:903] Comment for event 003 * SOURCE FILE: A181_C010_0913EA_001 
0

好吧,

我一直在嘗試使用NSScanner和線路前綴摸不着頭腦。 我可以掃描以數字開頭的行(事件),並隔離與每個相應事件相關的評論和效果。

下面的代碼:

for (NSString *line in psEdlLines)// just an NSLog test before scanning process 
    { 
     NSLog(@"Before scanner: %@",line);//All lines. 
    } 

for (NSString *line in psEdlLines)// Scanner process. 
     { 

     int eventNum; 
     NSString *comment; 
     NSString *effect; 
     NSScanner *lineScanner = [NSScanner scannerWithString:line]; 

while ([lineScanner scanInt:&eventNum]) 
     { 
      NSLog(@"Scanner: Event only: %@:", line); 
     } 

    if ([line hasPrefix:@"*"]) 
     { 
       comment = [line substringFromIndex:0]; 
      NSLog(@"Comment for event %03i: %@",eventNum, comment); 
     } 

    if ([line hasPrefix:@"M2"]) 
      { 
       effect = [line substringFromIndex:0]; 
      NSLog(@"Effect for event  %03i: %@",eventNum, effect); 
      } 
} 
@end 

下面是從3事件EDL文件輸出:

2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: TITLE: EP1 FINAL.EDL SECTION2 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: FCM: NON-DROP FRAME 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 001 A180_C00 V  C  20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: * SOURCE FILE: A180_C001_09138L_001 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 002 A181_C01 V  C  22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: * SOURCE FILE: A181_C010_0913EA_001 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 003 A181_C01 V  C  22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09 
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: M2 A181_C01  000.0    22:10:05:09 
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: * * FREEZE FRAME 
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: * SOURCE FILE: A181_C010_0913EA_001 
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: 
2012-03-23 14:23:48.041 TestProgram[1621:903] Scanner: Event only: 001 A180_C00 V  C  20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23: 
2012-03-23 14:23:48.041 TestProgram[1621:903] Comment for event 001 * SOURCE FILE: A180_C001_09138L_001 
2012-03-23 14:23:48.041 TestProgram[1621:903] Scanner: Event only: 002 A181_C01 V  C  22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04: 
2012-03-23 14:23:48.041 TestProgram[1621:903] Comment for event 002 * SOURCE FILE: A181_C010_0913EA_001 
2012-03-23 14:23:48.042 TestProgram[1621:903] Scanner: Event only: 003 A181_C01 V  C  22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09: 
2012-03-23 14:23:48.042 TestProgram[1621:903] Effect for event  003 M2 A181_C01  000.0    22:10:05:09 
2012-03-23 14:23:48.042 TestProgram[1621:903] Comment for event 003 * * FREEZE FRAME 
2012-03-23 14:23:48.042 TestProgram[1621:903] Comment for event 003 * SOURCE FILE: A181_C010_0913EA_001 

我可以if語句添加爲可以從EDL文件的註釋行出現的所有不測事件。 這應該允許我在循環內根據需要處理每一行元素。

這看起來好嗎?

謝謝, 皮特。