Add text to existing txt file [duplicate] - iphone

This question already has answers here:
write data line by line on iphone
(4 answers)
Closed 9 years ago.
How can I add text from UITextField, separated by comma to existing txt file?
I use this code:
NSString *imageName = [NSString stringWithFormat:#"Documents/text.txt"];
NSString *textPath = [NSHomeDirectory() stringByAppendingPathComponent:imageName];
NSString *word = [NSString stringWithFormat:#"%# ,", _wordInput.text];
[word writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
As you can see, I use this code to add a text from _wordInput which is my UITextField, and add comma. After that I use writeToFile option to write text to my text.txt file.
I tested, and works great, but, every time it will overwrite existing text..
Help please to NOT OVERWRITE TEXT, BUT separate by comma.
Let's say my UITextField has text "earth" at this moment, I will press a button, and the above code will run.. Now my text.txt file will contain "earth ," if I will enter another text on UITextField and run above code, the existing text will be overwrite, but I need it to be added after "earth ,"
Thanks.

It is better to use something like below function:
-(void)saveText:(NSString*)data
{
NSString *imageName = [NSString stringWithFormat:#"Documents/text.txt"];
NSString *textPath = [NSHomeDirectory() stringByAppendingPathComponent:imageName];
NSString *word = [NSString stringWithFormat:#"%# ,", _wordInput.text];
NSFileHandle *fileHandler= [NSFileHandle fileHandleForWritingAtPath:textPath];
[fileHandler seekToEndOfFile];
[fileHandler writeData:[word dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandler closeFile];
}

You need to include the original text when you write it back. Something like this:
NSString *imageName = [NSString stringWithFormat:#"Documents/text.txt"];
NSString *textPath = [NSHomeDirectory() stringByAppendingPathComponent:imageName];
NSString *existingFileContents = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:nil];
NSString *newFileContents = [NSString stringWithFormat:#"%#, %#", existingFileContents, _wordInput.text];
[newFileContents writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
I would assume that using system api calls like write() or fwrite() would be more efficient, but I've never measured it. If your text file is large, you might want to look into it.

Related

How to replace more than one common sub string in a single string with another string?

for(int i= 0 ;i<[urlsArrray count]; i++)
{
NSString *urlString = [urlsArrray objectAtIndex:i];
NSString *escapedUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:escapedUrlString];
NSString *urlstring1 = [url absoluteString];
NSArray *parts = [urlstring1 componentsSeparatedByString:#"/"];
NSString *fileName = [parts objectAtIndex:[parts count]-1];
NSMutableString *tempString = [NSMutableString stringWithString:fileName];
// [tempString replaceCharactersInRange:[tempString rangeOfString:#"%20"] withString:#" "];
NSLog(#"file name in temp string: %# word name: %#", tempString, wordNameDB);
NSRange match = [tempString rangeOfString:wordNameDB];
if(match.location != NSNotFound)
{
NSLog(#"match found at %u", match.location);
isAvailable = YES;
break;
}
Hi friends, now my problem is i am getting file name from server..., if file name is having any spaces then it replace '%20' ( i.e ex: "hello world" is actual name but i am getting file name like: "hello%20world") .
1. I am not sure all file names having spaces.
2. And also i am not sure a file may have only one space
so first i have to check the file is having spaces or not, if have then i want to replace all "%20" with #" " string. Please give me any suggestions or code snippets.
OR " THERE IA ANY OTHER WAY TO READ FILE NAMES WITHOUT GETTING '%20' IN THE PLACE OF SPACE(#" ")..... thank you
If you have your file name stored in fileName param, you can use the following:
fileName = [fileName stringByReplacingOccurrencesOfString:#"%20" withString:#" "];
The above code will replace all "%20" with " ". If there are no "%20" in the fileName, you will get back the same string.
Correction:
I was confused with stringByAddingPercentEscapesUsingEncoding mentioned in code and thought you have already used stringByReplacingPercentEscapesUsingEncoding. If you are not using stringByReplacingPercentEscapesUsingEncoding method, you should use that in this case. The above code is useful, only if that is not able to remove any particular string which you want to replace.
What you need is replacing the escape charcters, according to the encoding.
Use this and all your spaces and other URL encoded characters will be converted to what you need.
[#"yourString" stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
THERE IA ANY OTHER WAY TO READ FILE NAMES WITHOUT GETTING '%20' IN THE PLACE OF SPACE(#" ")
Yes, use this:
NSString *newString = [yourstring stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Use this to remove spaces ..
urlString = [urlString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
You seem to already have a valid NSURL object representing the file. Getting the filename from a URL is easy:
...
NSURL *url = [NSURL URLWithString:escapedUrlString];
NSString *path = [url path];
NSString *filename = [path lastPathComponent];
No fiddling with unescaping percent escapes, URL parsing, and other error prone stuff.

Using writeToFile:atomically: consecutively doesn't work...why?

I'm trying to write a csv file. I have two arrays at hand - one with the titles (Name, Number etc), another with the actual values (Jon, 123 ...).
Now, after the following two operations:
[[titles componentsJoinedByString:#", "] writeToFile:file atomically:YES];
[[values componentsJoinedByString:#", "] writeToFile:file atomically:YES];
only the values array is written to the file. I realise that I may need to open the file again, but how do I do that after writing the first array? Or what is it exactly that I'm doing wrong if this is not the case?
Thanks!
The second line is in fact overwriting the file you wrote in the first line. One simple way to get around this problem would be to simply append the second string to the first (likely with an '\n' in between since you're making a csv file) and writing that string to your file:
NSString *str1 = [[titles componentsJoinedByString:#", "];
NSString *str2 = [[values componentsJoinedByString:#", "];
NSString *outputStr = [str1 stringByAppendingFormat:#"\n%#", str2];
[outputStr writeToFile:file atomically:YES];
Second time it replaces the old contents. So you could read the old content, append the old content with the new content and save on file.
Write first row
[[titles componentsJoinedByString:#", "] writeToFile:file atomically:YES];
Where you need to add another row every time
NSString *previousContent = [[NSString alloc] initWithContentsOfFile:file usedEncoding:nil error:nil];
NSString *str2 = [[values componentsJoinedByString:#", "];
NSString *outputStr = [previousContent stringByAppendingFormat:#"\n%#", str2];
[outputStr writeToFile:file atomically:YES];

read text file with delimiter nsstring

I have a text file like this
question1
question2
question3
I want to read only the first line into a nsstring
after that I want to mark the first line so the next time, skip the first line, but I don't know how to do it, I have this code for read but give me only the third line
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"qa" ofType:#"txt"];
NSString *myText = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [myText componentsSeparatedByString:#"\n"];
for(myText in lines)
{
texview.text = myText;
}
}
Ok I try this code, Do not work, what I am Doing wrong?
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString * const kKey = #"OneTimeKey";
NSObject *keyValue = [defaults objectForKey:kKey];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"qa" ofType:#"txt"];
NSString *myText = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [myText componentsSeparatedByString:#"|"];
if (keyValue==nil) {
for(myText in lines)
{
preguntadia.text = myText;
[defaults setBool:YES forKey:kKey];
}
}
The problem is that your "for" is executed really fast, so fast that you can only see when the last element of the array is set to your text view.
What you can do is have a variable which specifies which one of the strings to show next and, with a timer, set a different string on your text view every number of seconds, so you can actually see the changes.
Bonus, you can make it cycle with something like this:
-(void)updateText{
[textView setText:[lines objectAtIndex:currentIndex]];
currentIndex++;
currentIndex = currentIndex % [lines count];
}
So when it reaches the last string, it shows the first again.
You'll need to store a line counter locally to keep track, I think. That is easily accomplished with something like this to save:
[[NSUserDefaults standardDefaults] setInteger:lineCount forKey:#"lineCountKey"];
and fetch:
int lineCount = [[NSUserDefaults standardDefaults] integerForKey:#"lineCountKey"];
and then just read and discard lineCount lines when you open the file.
Now, splitting the line you want into multiple pieces, you can use the NSString method componentsSeparatedByString:, but be careful. If your "questions" are actually multi-word questions, you'll need to pick a separator other than space. Vertical bar (|) might be a good choice, then you can do something like this:
NSArray *questions = [line componentsSeparatedByString:#"|"];
NB: Code typed from memory; not compiled. :-)

Creating an array from a text file read from a URL

I am reading a text file from a URL and want to parse the contents of the file into an array. Below is a snippet of the code I am using. I want to be able to place each line of the text into the next row of the array. Is there a way to identify the carriage return/line feed during or after the text has been retrieved?
NSURL *url = [NSURL URLWithString:kTextURL];
textView.text = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
When separating by newline characters it's best to use the following procedure:
NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet];
NSArray *lineComponents = [textFile componentsSeparatedByCharactersInSet:newlines];
This ensures that you get lines separated by either CR, CR+LF, or NEL.
You can use NSString's -componentsSeparatedByString: method, which will return to you an NSArray:
NSURL *url = [NSURL URLWithString:kTextURL];
NSString *response = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding];
textView.text = response;
NSArray *lines = [response componentsSeparatedByString:#"\n"];
//iterate through the lines...
for(NSString *line in lines) {
//do something with line...
}

Troubles with NSString writeToFile

I am using the following code to open a file's contents and save it to another file.
when it runs the original file length is 793 but the saved file is 0. I have also tried just to copy the file. Nothing seems to work.
Is there some kind of permissions I'm missing on the documents directory?
NSError *error;
NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* nGram = [basePath stringByAppendingPathComponent:#"contacts.gram"];
NSString *oGram = [basePath stringByAppendingPathComponent:#"/../vText.app/model/lm/TAR9230/contacts.gram"];
NSString *gramString = [[NSString alloc] initWithContentsOfFile:oGram encoding:NSUTF8StringEncoding error:&error];
BOOL ok = [gramString writeToFile:nGram atomically:NO encoding:NSUnicodeStringEncoding error:&error];
if(!ok) NSLog(#"Mayday!");
NSLog(#"%d",[gramString length]);
gramString = [[NSString alloc] initWithContentsOfFile:nGram encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%d",[gramString length]);
This entire block is unnecessary. All you need is:
NSString *fp=[[NSBundle mainBundle] pathForResource:#"contacts" ofType:#"gram"];
NSString *gramString = [[NSString alloc] initWithContentsOfFile:fp
encoding:NSUTF8StringEncoding
error:&error];
You certainly don't want to try to directly access a file in the app bundle using a hardcoded path because the file isn't guaranteed to be in the same exact place in every build.
In the code you do have, you want to use the same encoding constant for reading as you did for writing. You write with NSUnicodeStringEncoding but you read with NSUTF8StringEncoding. These should overlap but why take the chance if you know the exact coding used?