escaping quates in a string.

Discussion in 'Mac Programming' started by larswik, Sep 8, 2012.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    I have a text document that I created and added hundreds of words to it, 1 for each line. I creating a little helper app to convert these, then resave to a text file. Then I can copy / paste them into an NSArray for my program since they are already formatted.

    My string needs to look like this @"@"Driving","; So I am taking the word Driving and adding @" in front of it and then another quotation mark and coma at the end like this ",

    The NSString also has the @""; formatting around that. When I write a new text file to the desktop I can then just copy / paste that information into my NSArray.

    I didn't want to have text documents to be imported into my main app so I thought I could write a little helper program to convert these, then just paste the Array entries in with the proper formating.

    My code
    Code:
    -(void)parseData{
        NSArray *lines = [contentsOfFile componentsSeparatedByString:@"\n"];
        for (NSString *aKey in lines) {
            if (aKey.length != 0) {
                NSString *saveString = [NSString stringWithFormat:@"@\"%@\"",aKey];
                [fileBreakDown addObject:[saveString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    
            }
        NSLog(@"%@", fileBreakDown);
        }
    }
    
    
    I thought I could just escape the quote like so \" but when I add it to the array I ended up with this
    instead of what I wanted which would be
    Is there a way to correctly escape the quotes to do this?
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    I'm not sure what you're trying to accomplish. Whatever it is, we need to see the file that's being produced by the helper app. After showing that data, please describe what it should be.

    You should also post an example of the input data to the helper app. The purpose of posting data is so people can duplicate what you're seeing, and even write code to do what you want to happen. Right now, we have a somewhat vague description of data, rather than actual examples of data.
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    Hi Chown33,

    I am working on an experience points tracking app for an RPG game. The game has many skills the user can select from. I have friends that are helping me convert the different skills from the different books and they are sending me text documents with words like Driving, Dragon Lore, physics and so on.

    The end result is to get these in to a UITableView the user selects from. So I need to create a NSArray to hold the data. I have 2 options for this that I can see. 1 is to import the text documents, parse the data and add it to an NSArray to populate the TableView. Or 2 was to just copy the information from the text files and paste it into an NSArray. The second method was easier and I did not have to add more code to the experience tracking program to parse data.

    The problem I have with NSArray *skillsArray = [NSArray arrayWithObjects.... is the formatting for each object. The array objects need to be formatted with the AT symbol '@' and quotes around the string followed by a comma, ie, @"theWord", .

    I thought this would be a great opportunity to write a small Mac helper program. I could read in the contents of the txt files from my friends, format it with @"", and re save a text file to the desktop again. So the imported text file would have a line of text like this: Driving Skill and the exported txt file would have this: @"Driving Skill", which is the proper format for an object in an NSArray.

    I could then simply copy and paste that data from the new text file right into my NSArray *skillsArray = [NSArray arrayWithObjects: @"Driving Skill", nil]; Below are my 2 methods to create a NSOpenPanel to select the file and then to parse the data. That was as far as I got.

    The problem is that I am using the backslash '\' to escape the quotation. Example @"The man said \"Hello World\""; When I NSLog this it says: The man said "Hello World". But when I try and add this to an NSMutableArray the backslashes are still there, They should be removed from the string. I also included sample text file.

    Code:
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        fileBreakDown = [[NSMutableArray alloc] init];
        
    }
    - (IBAction)selectFile:(id)sender {
            
        NSOpenPanel *panel = [NSOpenPanel openPanel];
        [panel setCanChooseFiles:YES];
        [panel setCanChooseDirectories:NO];
        [panel setAllowsMultipleSelection:NO]; // yes if more than one dir is allowed
        
        NSInteger clicked = [panel runModal];
        
        if (clicked == NSFileHandlingPanelOKButton) {
            for (NSURL *url in [panel URLs]) {
                contentsOfFile = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
            }
        }
        [self parseData];
    }
    
    -(void)parseData{
        NSArray *lines = [contentsOfFile componentsSeparatedByString:@"\n"];
        for (NSString *aKey in lines) {
            if (aKey.length != 0) {
                NSString *saveString = [NSString stringWithFormat:@"@\"%@\"",aKey];
                [fileBreakDown addObject:[saveString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    
            }
        }
        NSLog(@"%@", fileBreakDown);
    }
    
    I don't know if it is possible to do this?
     

    Attached Files:

  4. chown33, Sep 8, 2012
    Last edited: Sep 8, 2012

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Please post the output file produced by the helper program. Or are you saying that you don't have that part working yet? It's hard to tell, because you didn't post a complete class, so I can't tell what you've left out. You've certainly left out some parts of the class, and I can't guess what else you've left out.

    Long explanations aren't necessary. Simply post the data, post the code, and describe what the output data should look like.

    Be specific.

    For example, if the input data is this:
    Code:
    Administration
    Advanced Math 
    Alchemy 
    
    you want the output data to be this:
    Code:
    @"Administration",
    @"Advanced Math",
    @"Alchemy",
    
    Your answer should be either "Yes" or "No". If that's not what you want the output data to look like, you need to post a specific example.

    You also need to identify any special cases that might appear in your input data, such as literal double-quotes that need to be escaped in the output. Example input data:
    Code:
    I said, "Quote me"!
    
    and output data:
    Code:
    @"I said, \"Quote me\"!",
    

    Finally, I wouldn't write an Objective-C program for this. Instead, I'd write a awk program. You may not know awk, so I'll post one later that works with the data you've posted so far.

    EDIT

    File "quoter.awk":
    Code:
    # Performed for each line
    {
      # trims leading & trailing whitespace of $0
      # ref: #27 at http://www.catonmat.net/blog/awk-one-liners-explained-part-two/
      gsub( /^[ \t]+|[ \t]+$/, "" )
    
      # trimmed result is in $0
      print "@\"" $0 "\","
    }
    
    END { print "nil" }
    
    Example command-line:
    Code:
    awk -f quoter.awk  Academic.txt >output.txt
    
    Sample input (from Academic.txt):
    Code:
    Basic Mathematics 
    Biochemistry 
    Boat Pilot
    Demon/Devil Lore 
    
    Sample output:
    Code:
    @"Basic Mathematics",
    @"Biochemistry",
    @"Boat Pilot",
    @"Demon/Devil Lore",
    
    If the input is in several text files, just list them on the command-line, like so:
    Code:
    awk -f quoter.awk  Academic.txt More.txt StillMore.txt >output.txt
    

    NOTE: doesn't handle double-quotes that appear in any input data. If you want that, post a request for it.

    If you want to write your own program in Objective-C, I strongly suggest writing the array to a file, where you can actually see the output. Viewing logs and assuming outputs is a risky business. If that seems obtuse or counter-intuitive, I suggest writing the code that writes the array to a file.
     
  5. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #5
    You got what I was trying to explain. The input data and the output data were exactly like you posted. The goal was to write out the file like you explained. As I was writing the code I was testing it as I went along to make sure the results were as expected.

    I have never even heard of "awk" before. I will try and wrap my head around that so I better understand it. But I am curious why I could not do the same thing in Object C?

    None the less I do very much appreciate you taking the time as you always do. I'll make it an awk night tonight, always eager to learn.

    Thanks.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    You can write it in any language that's sufficiently capable. That's at least hundreds of possibilities, since I'm quite certain there are hundreds of different languages that are sufficiently capable.

    It's really a question of ease, which covers a wide range of things.

    First is intrinsic language capability. Awk was designed and created as a pattern-matching and text-processing language. That means it has pattern-matching and text-processing features both builtin and easily accessible.

    In other languages, you typically have to open a file, read it in, split it up, and then process each line. For example, look at your Objective-C code for reading a URL, splitting it at newlines, and making an array of strings. In awk, that's all done "by magic", so an awk program magically receives lines of text that are produced by reading the list of filenames on the command-line. All you do is write a series of pattern/action match possibilities, and the rest is done for you.

    Another element of ease is how easy it is to make changes.

    I didn't write that awk program in one sitting. I first googled for a way to trim whitespace from lines (see the URL in the code). Then I simply ran that on the previously posted "Academic.txt" file. Then it was a couple of changes, save and rerun (no compile needed), and boom there it was. All done in TextEdit.app (no Xcode needed), using copy/paste to paste a command-line into Terminal from another text file.
     
  7. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #7
    If I'm understanding you correctly, there's no issue with the string retaining its backslashes when added to a mutable array. They're still the same and it's just the difference between how an NSString prints itself and how NSStrings inside an array are printed. For example, this:

    Code:
    NSLog(@"\"Hello\" World");
    NSLog(@"%@", @[@"\"Hello\" World"]);
    NSLog(@"%@", @[@"\"Hello\" World"][0]);
    
    Logs:

    Code:
    "Hello" World
    (
        "\"Hello\" World"
    )
    "Hello" World
    
    Alternatively, have you considered using smart quotes (“” and ‘’) instead? If the strings are going to be displayed to a user, it's usually preferred and requires no escaping. The NSLinguisticTagger class provides a nice way to detect opening and closing quotes to do the substitution yourself.
     
  8. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #8
    I spent last night read about awk like chown33 recommended. But if I understand you correctly when I finish the objective C app and read in a txt file with this contents
    the end result after writing to a new txt file will be
    It's just the nature of NSLog when displaying the contents of an array to show everything including the backslash?

    Now I am curious. Tonight I will finish the program and write to a txt file and see if 'escape' are removed from the output.
     

Share This Page