Quirk disappearing white space string - objective-c

I run into this funny situation. I create a string containing only white space. Spaces and newlines. No matter if I create it randomly or using a loop inside a loop (lots of spaces followed by a newline). When I log the string it does not show up? Even the newline in
NSLog(#"String\n%#",s);
disappears. If I add anything that is not whitespace to s then it shows up.
Here is the code to reproduce it.
#import <Foundation/Foundation.h>
NSString * func ( BOOL f )
{
// Create a string containing only white space
NSMutableString * s = NSMutableString.string;
BOOL rand = NO;
if ( rand )
{
for ( int i = 0; i < 500; i ++ )
{
if ( arc4random_uniform(100) > 90 )
{
[s appendString:#"\n"];
}
else
{
[s appendString:#" "];
}
}
}
else
{
for ( int i = 0; i < 10; i ++ )
{
for ( int j = 0; j < 100; j ++ )
{
[s appendString:#" "];
}
[s appendString:#"\n"];
}
}
if ( f )
{
[s appendString:#"?\n"];
}
return s;
}
int main(int argc, const char * argv[]) {
#autoreleasepool
{
// insert code here...
NSLog(#"Hello, World!");
NSLog(#"The string is\n%#",func(NO));
NSLog(#"Where is it?");
// Now add something real
NSLog(#"The string is\n%#",func(YES));
NSLog(#"Oh there it is?");
}
return 0;
}
Note in main the first time func is called with BOOL NO as argument, the function just creates a bunch of whitespace. So I'd expect to see it in the log. However, the log shows nothing! Not even the newline!
Then I call the function again. This time it generates the same thing but postfixes it with a question mark and suddenly the string appears. Where did the whitespace go? Is there some funny optimisation going on? Looks like a bug.
Here is the output for reference.
2021-01-23 21:28:43.990972+0200 WhiteSpaceString[33439:733772] Hello, World!
2021-01-23 21:28:43.991845+0200 WhiteSpaceString[33439:733772] The string is
2021-01-23 21:28:43.991943+0200 WhiteSpaceString[33439:733772] Where is it?
2021-01-23 21:28:43.992171+0200 WhiteSpaceString[33439:733772] The string is
?
2021-01-23 21:28:43.997993+0200 WhiteSpaceString[33439:733772] Oh there it is?
Program ended with exit code: 0
Initially I thought maybe the function is to blame, as it returns a string but internally uses a mutable string. But even if the code is put inside main e.g.
NSMutableString * t = NSMutableString.string;
for ( int i = 0; i < 10; i ++ )
{
for ( int j = 0; j < 100; j ++ )
{
[t appendString:#" "];
}
[t appendString:#"\n"];
}
NSLog(#"The string is\n%#",t);
it still does not show the string.

Related

Project Euler # 10 in Objective C

I'm trying to solve Problem 10 in Project Euler, and while I thought I had it, its saying my answer is incorrect. The question is as follows:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
And my code:
int sum;
#interface Prime : NSObject
-(BOOL)isPrime:(int)arg1;
#end
#implementation Prime
-(BOOL)isPrime:(int)arg1 {
if (arg1 == 1) {
NSLog(#"Given 1");
return NO;
}
for (int i = 2; i < arg1; i++) {
if (arg1 % i == 0) {
return NO;
}
}
sum += arg1;
return YES;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
Prime* primeObject = [[Prime alloc] init];
for (int i = 0; i < 2000000; i++) {
[primeObject isPrime:i];
}
NSLog(#"Sum of primes is %i", sum);
}
}
This code outputs 'Sum of primes is 1179908154' which Project Euler says is incorrect. Help?
The problem is that the sum does not fit into a 32-bit integer. You should use long long instead.
Just a guess, you should try to:
Initialise the sum variable to 0.
Try not to use a global variable like sum that can be accessed from anywhere, in this case do the sum in the main loop instead of in the isPrime method.
Maybe that'll give you the right answer.
You are using int for getting result, so it is wrong.
I'm using long int instead, that is enough for this case.
Here is my code, and it works fine:
int inputNumber = 2000000;
long int result = 0;
for (int i = 2; i < inputNumber; i++) {
BOOL isPrime = YES;
for (int j = 2; j <= sqrt(i); j++) {
if (i%j==0) {
isPrime = NO;
break;
}
}
if (isPrime) {
result += i;
}
}
Result is: 142913828922

malloc error when reading file in iOS

i have this function that reads a line from a file character by character and inserts it into a NSString.
RANDOMNLY the system crashes with this error:
malloc: *** error for object 0x1e1f6a00: incorrect checksum for freed
object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
function:
NSDictionary *readLineAsNSString(FILE *f,int pospass,
BOOL testata, int dimensioneriga)
{
char *strRet = (char *)malloc(BUFSIZ);
int size = BUFSIZ;
BOOL finito=NO;
int pos = 0;
int c;
fseek(f,pospass,SEEK_SET);
do{ // read one line
c = fgetc(f);
//Array expansion
if (pos >= size-1) {
size=size+BUFSIZ;
strRet = (char *)realloc(strRet, size);
}
if(c != EOF) {
strRet[pos] = c;
pos=pos+1;
}
if(c == EOF) {
finito=YES;
}
} while(c != EOF && c != '\n');
if (pos!=0) {
for (int i = pos; i<=strlen(strRet)-1; i++) //size al posto di pos
{
strRet[i] = ' ';
}
}
NSString *stringa;
if (pos!=0) {
stringa=[NSString stringWithCString:strRet encoding:NSASCIIStringEncoding];
} else {
stringa=#"";
}
long long sizerecord;
if (pos!=0) {
sizerecord= (long long) [[NSString stringWithFormat:#"%ld",sizeof(char)*(pos)] longLongValue];
} else {
sizerecord=0;
}
pos = pospass + pos;
NSDictionary *risultatoc = #{st_risultatofunzione: stringa,
st_criterio: [NSString stringWithFormat:#"%d",pos],
st_finito: [NSNumber numberWithBool:finito],
st_size: [NSNumber numberWithLongLong: sizerecord]
};
//free
free(strRet);
return risultatoc;
}
where "finito" is a flag, "pos" is the position in the file line,"pospass" is the position in the entire file, "c" is the character, "strRet" is the line and BUFSIZ is 1024.
Each file has n line with the same lenght (for file).
Thanks!!!
This part:
if (pos!=0) {
for (int i = pos; i<=strlen(strRet)-1; i++) //size al posto di pos
{
strRet[i] = ' ';
}
}
is broken. strlen just reads until it finds a \0 ... since you didn't put one in, it can just keep reading off the end of your buffer.
You already have size, so just use that, or better still just terminate strRet instead of right-filling with spaces:
strRet[pos] = '\0';

Why do i get "program received signal: "EXC_BAD_ACCESS" on NSString veriable

I just recently started learning Objective C, when i run the next program i get error
"program received signal: "EXC_BAD_ACCESS"
For the code line
if([*userChoice isEqualToString:#"yes"])
The full code is:
void initGame (void);
void restartGame(void);
void toGoOn(char *playerChoice);
int guess=-1;
int from=-1;
int to=-1;
bool playStatus=true;
bool gameStatus=true;
int answer=-1;
NSString *userChoice[10];
//if true the game is on
int main (int argc, const char * argv[])
{
#autoreleasepool {
GuessManager *game=GUESS;
NSLog(#"Hello, lets play");
NSLog(#"Please provide a positive range in which you would like to play");
do{
initGame();
[game setnumberToGuess:from :to];
do {
printf("Make you guess:");
scanf("%d", &guess);
[game setUserGuess:guess];
[game checkUserGuess];
if([game getDidIgetIt])
{
playStatus=false;
}
else
{
playStatus=true;
}
} while (playStatus);
restartGame();
}while(gameStatus);
printf("Thanks For Playing PanGogi Games! GoodBye");
}
return 0;
}
void initGame (void)
{
printf("from:");
scanf("%d",&from);
printf("to:");
scanf("%d",&to);
}
void restartGame(void)
{
printf("Would you like to continue?(yes/no)");
scanf("%s",&userChoice);
//scanf("%d",&answer);
// if(answer==1)
if([*userChoice isEqualToString:#"yes"])
{
gameStatus=true;
}
else
{
gameStatus=false;
}
}
I understand that its related to the NSString variable userChoice and how its used in
the if, but what i cant find is what am i doing wrong.
Please help :)
You have 3 errors in the code
1) I think you are getting confused with NSString and C style char array... You just need to use single NSString object to save multi character data..
NSString *userChoice;
2) Since you want to input data using scanf, you need a C style character array. scanf won't work with NSString types.
char tempArray[10];
int count = scanf("%s",&tempArray);
userChoice = [NSString stringWithBytes:tempArray length:count encoding: NSUTF8StringEncoding];
3) Now you can use NSString directly.. No need for pointer like syntax
if( [userChoice isEqualToString: #"yes"]){
.....
.....
}
You're using NSString as if it was char. It's not. It's a class that represents a string.
The scanf function is a C function and needs a char array, not an NSString.
char str[80];
scanf("%s", &str);
You can initialize an NSString object with a char array like this:
NSString *userChoice = [NSString stringWithCString:str encoding:NSASCIIEncoding];
And compare like this:
if ([userChoice isEqualToString:#"yes"]) {
...
} else {
...
}

Converting NSString to array of chars inside For Loop

I'm trying to use an existing piece of code in an iOS project to alphabetize a list of words in an array (for instance, to make tomato into amoott, or stack into ackst). The code seems to work if I run it on its own, but I'm trying to integrate it into my existing app.
Each word I want it to alphabetize is stored as an NSString inside an array. The issue seems to be that the code takes the word as an array of chars, and I can't get my NSStrings into that format.
If I use string = [currentWord UTFString], I get an error of Array type char[128] is not assignable, and if I try to create the char array inside the loop (const char *string = [curentWord UTF8String]) I get warnings relating to Initializing char with type const char discards qualifiers. Not quite sure how I can get around it – any tips? The method is below, I'll take care of storing the alphabetized versions later.
- (void) alphabetizeWord {
char string[128], temp;
int n, i, j;
for (NSString* currentWord in wordsList) {
n = [currentWord length];
for (i = 0; i < n-1; i++) {
for (j = i+1; j < n; j++) {
if (string[i] > string[j]) {
temp = string[i];
string[i] = string[j];
string[j] = temp;
}
}
}
NSLog(#"The word %# in alphabetical order is %s", currentWord, string);
}
}
This should work :
- (void)alphabetizeWord {
char str[128];
for (NSString *currentWord in wordList)
{
int wordLength = [currentWord length];
for (int i = 0; i < wordLength; i++)
{
str[i] = [currentWord characterAtIndex:i];
}
// Adding the termination char
str[wordLength] = 0;
// Add your word
}
}
EDIT : Sorry, didn't fully understand at first. Gonna check this out.

how to print characterSet in objective c?

i'm using GNUstep shell for programming objective-c. I'm able to convert string to a character set. But unable to print the converted character set in the console. Please tell me a way to print it. Thanks in advance.
This will do the first 65536 characters in unicode, which will do for most situations. I believe unicode can go much higher (2^32?), but this would take much longer to log.
+ (void) logCharacterSet:(NSCharacterSet*)characterSet
{
unichar unicharBuffer[20];
int index = 0;
for (unichar uc = 0; uc < (0xFFFF); uc ++)
{
if ([characterSet characterIsMember:uc])
{
unicharBuffer[index] = uc;
index ++;
if (index == 20)
{
NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
NSLog(#"%#", characters);
index = 0;
}
}
}
if (index != 0)
{
NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
NSLog(#"%#", characters);
}
}
There are some quite fun looking results, for example here is a sample of 20 characters from punctuationCharacterSet.
༅༆༇༈༉༊་༌།༎༏༐༑༒༔༺༻༼༽྅