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. :-)
Related
NSDictionary *allDatDictionary = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
NSDictionary *responseData = [allDatDictionary objectForKey:#"responseData"];
NSDictionary *arrayOfResult = [responseData objectForKey:#"results"];
for (NSDictionary *diction in arrayOfResult) {
NSString *title = [diction objectForKey:#"title"];
NSString *content = [diction objectForKey:#"content"];
NSString *url = [diction objectForKey:#"url"];
[array addObject:title];
[content1 addObject:content];
[url1 addObject:url];
NSLog(#"title: %#, \n Content: %# \n, Url: %# \n", [diction objectForKey:#"title"], [diction objectForKey:#"content"],[diction objectForKey:#"url"]);
NSString *text = #"";
text = [NSString stringWithFormat:#"Title: %#%#\nURL: %#\nContent: %#\n\n", text, [diction objectForKey:#"title"],[diction objectForKey:#"url"],[diction objectForKey:#"content"]];
Hey guys, I got the json and I need to show title, content and url on screen. I don't need table ranting like this just show on screen. NSLog shows everything but when I try to write on a UILabel it just shows 1 result. Any tips how I can do that? thanks
You're setting labelTitle's text in a for loop, so you're only going to see the last result, because you keep changing it each time thru the loop. If you want to see all of the results, you'll have to build up a string that contains all of them and then set that as the text of the label.
At the top of the for loop, declare an NSString variable and set it to #"", like the following:
NSString *text = #"";
Then each time thru the loop, instead of setting the label text to your string, build up this string that you're saving at the top, like the following:
text = [NSString stringWithFormat:#"%#%#\n", text, [diction objectForKey:#"title"]];
You can see how I modified that format string. It takes the previous text you've saved, adds to it your new title, and then adds a carriage return.
As an alternative, you could have an NSMutableArray at the top, and add your strings to that array each time you go thru the for loop. Then at the end, you can use the NSArray method componentsJoinedByString:, using a carriage return as the separator, to get an NSString containing all of the individual strings that you added to the array.
After you have this one string, using either of these methods, you can set that as the text on the label.
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.
I am kind of new to iOS development.
I want to retrieve strings from the text(.rtf) file I have. The file is within my application main bundle. It's content are:
#start word1 First word end word2 Second word end //lots of things to be added later
Code:
path = [[NSBundle mainBundle]pathForResource:#"words" ofType:#"rtf"];
if(path)
{
NSLog(#"path exists");
}
NSError *error = nil;
NSString *file = [[NSString alloc]initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if(error)
{
NSLog(#"error");
}
NSString *finalword= [[NSString alloc]init ];
NSString *startfrom = [[NSString alloc] initWithFormat:#"word%i",i+1];
i++;
NSLog(#"%#",startfrom);
NSString *wordoftheday = [[NSString alloc]init ];
NSScanner *scanner = [NSScanner scannerWithString:file];
[scanner scanUpToString:startfrom intoString:nil];
[scanner scanUpToString:#"end" intoString:&wordoftheday];
finalword = [wordoftheday substringFromIndex:[startfrom length]];
NSLog(#"%#",finalword);
Word.text = final word; //change label text
//[final word release];
//[wordoftheday release];
//[file release];
Code is working fine but it leaves me with memory management issues. App crashes if I release the variables in the last commented code.
Also this method is in my viewdidload. I want the label to change text when user click a button. I will have to write the same code again in that method which leaves me with more memory issue.
So looking at these one by one, focusing on the memory issues and not the overall strategy here:
NSString *finalword= [[NSString alloc]init ];
Here you alloc/init a new immutable and empty NSString, and then you end up overwriting the pointer to this later anyway. You should just delete this line. And then you'll need to move the declaration down a few lines to this:
NSString *finalword = [wordoftheday substringFromIndex:[startfrom length]];
Then you have:
NSString *startfrom = [[NSString alloc] initWithFormat:#"word%i",i+1];
This one you need to release later. Or just change it to:
NSString *startfrom = [NSString stringWithFormat:#"word%i",i+1];
Then you have:
NSString *wordoftheday = [[NSString alloc]init ];
Same story as finalword. Except that you do need to define this variable so you can pass it to the scanner later. So change it to:
NSString *wordoftheday = nil;
And lastly, you can release 'file'. That is fine. But you don't want to release 'wordoftheday' or 'finalword' because you don't own those strings. You did not create them yourself.
And one other note:
if(error)
That is not the correct way to check for an error in loading 'file'. You should check the return from the method and then look for an error if and only if the return value was nil. So change that line to:
if(!file)
(OK, that wasn't really a memory issue, but a bug I did notice.)
I think that's all of it at least as far as memory issues. I hope that helps.
make those variables as member variables and release in the dealloc
I found this snippet online to write, and then append data to a text file:
- (void)appendText:(NSString *)text toFile:(NSString *)filePath {
// NSFileHandle won't create the file for us, so we need to check to make sure it exists
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:filePath]) {
// the file doesn't exist yet, so we can just write out the text using the
// NSString convenience method
NSError *error = noErr;
BOOL success = [text writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!success) {
// handle the error
NSLog(#"%#", error);
}
}
else {
// the file already exists, so we should append the text to the end
// get a handle to the file
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
// move to the end of the file
[fileHandle seekToEndOfFile];
// convert the string to an NSData object
NSData *textData = [text dataUsingEncoding:NSUTF8StringEncoding];
// write the data to the end of the file
[fileHandle writeData:textData];
// clean up
[fileHandle closeFile];
}
}
This makes sense to me. I have a class that has 3 properties, of NSString, NSInteger, and NSString. When I try to use this method, I do this:
for (MyObject *ref in array) {
NSString *stringToFile = [NSString stringWithFormat:#"%#\t%i\t%#", ref.ChrID, ref.Position, ref.Sequence];
[self appendText:stringToFile toFile:filePath];
}
It doesn't look quite right. My data looks like this:
NSString *tab* NSInteger *single space* NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
NSStringNSString *tab* NSInteger newline
...
I'm not sure what is going on to make it look like this. When I NSLog the data, it looks fine. But something with the first line gets messed up, and then everything seems to be off. Any thoughts? Thanks.
There are several issues with the method appendText:
if the file does not exist, the first line is written with the NSString writeToFile method without the \n
following lines are written with the NSData writeData method
it's very inefficient to use a filemanager to check for existence, get a filehandle, seek to EOF and then write just one line, omitting the close too. And repeating this for every following line.
So better do it this way:
get the filehandle for writing, it will be created if it's not there yet
seek to EOF
do your loop with writeData for each line
close the file
I have a txt file with some URLs like this
http://url1.com
http://url1.com
http://url1.com
Separated by a line break. How could I add those as different entries separated by line breaks to an NSMutableArray? Thanks :)
Try something like this:
NSMutableArray *txtLines = [NSMutableArray array];
[txtFile enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
if ([line length] > 0) {
[txtLines addObject:line];
}
}];
Update
#Evan is right, the above only works if blocks are available on your platform. A compiler directive around that code should take care of this limitation, e.g.:
#if NS_BLOCKS_AVAILABLE
// iOS 4.0+ solution
#else
// iOS 2.0+ solution
#endif
NSString *myListString = /* load / download file */
NSMutableArray *myList = [myListString componentsSeparatedByString:#"\n"];
You may have to use <br/> if it's HTML.
#octy's solution is only available in iOS 4.0 or later. This solution is iOS 2.0 or later. You can check the iOS version and choose which one to use:
BOOL useEnumeratedLineParsing = FALSE;
NSString *reqSysVer = #"4.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
useEnumeratedLineParsing = TRUE;
Then check the value of useEnumeratedLineParsing.
NSString *textFilePath = [[NSBundle mainBundle] pathForResource:#"urls" ofType:#"txt"];
NSString *fileContentsUrls = [NSString stringWithContentsOfFile:textFilePath encoding:NSUTF8StringEncoding error:nil];
NSArray *myArray = [urls componentsSeparatedByString:#"\n"];
As long as it isn't mega-large, you could read the whole file into an NSString.
NSString *text = [NSString stringWithContentsOfFile:path encoding:NSUTF8Encoding error:nil];
Then split the lines:
NSArray *lines = [text componentsSeparatedByString:#"\n"];
And make it mutable:
NSMutableArray *mutableLines = [lines mutableCopy];
Now, depending on where your text file is coming from, you probably need to be more careful. It could be separated by \r\n instead of just \n, in which case your lines will contain a bunch of extra \r characters. You could clean this up after the fact, using something to remove extra whitespace (your file also might have blank lines which the above will turn into empty strings).
On the other hand, if you're in control of the file, you won't have to worry about that. (But in that case, why not read a plist instead parsing a plain text file...)