Challenge - C Strings


#1

Here is my answer for the challenge
However I think it is incomplete as Aaron mentions "when you run into ‘\0’, you have reached the end of the string"
I never used that in my solution - but am thinking I should have.

My spaceCount Function


int spaceCount (const char *s)
{
    int NumSpace=0;
    for (int i = 0; i < strlen(s); i++) {
    
        if (s[i]==0x20) {
            NumSpace++;
            
        }
    }
    
    return NumSpace;
    
}

#2

Your solution is fine. You used strlen() to figure out where the ‘\0’ is. This is less efficient (as you walk the string once in strlen() and then again in your loop), but it is a perfectly acceptable solution.


#3

Thanks Aaron for your replies and help through this book - Its awesome, its like having a teacher mark your work!
My background is in Visual Basic, so the move to Objective C or in fact C in general has been huge, so this book has been a God send.

Regards
Toddy


#4

Ok. good point.

how about this?

[code]int spaceCount(const char *c)
{
int i = 0;
int count = 0;

while (1) {
    if (c[i] == 0x20)
        count++;
    else if (c[i] == '\0')
        break;
    i++;
}
return count;

}
[/code]


#5

Looks reasonable, tappdarden. Another option, making use of a for loop instead of while:

int spaceCount(const char *c)
{
  int count = 0;
  int i;
  for (i = 0; c[i] != '\0'; i++)  {
    if (c[i] == ' ') {
      count++;
    }
  }
  return count;
}

#6

My solution:

int spaceCount (const char *inString) { int i = 0; int countSpaces = 0; while (inString[i] != '\0') { if (inString[i] == 0x20) { countSpaces++; } i++; } return countSpaces; }


#7

So for some added fun, instead of calling a function spaceCount, I modified my solution to use a Block

[code] int (^spaceCountBlock)(const char *inStringBlock);

    spaceCountBlock = ^(const char *inStringBlock) {
        int i = 0;
        int countSpaces = 0;
        while (inStringBlock[i] != '\0') {
            if (inStringBlock[i] == 0x20) {
                countSpaces++;
            }
            i++;
        }    
        return countSpaces;
    };
    
    printf("\"%s\" has %d spaces\n", sentence, spaceCountBlock(sentence));

[/code]

What I would like to do now, is implement the block within the printf so that the last argument was the block. Seems like a logical use of a block. My problem so far, the block never executes

[code]printf(""%s" has %d spaces\n", sentence, (int) ^ {
int i = 0;
int countSpaces = 0;
while (sentence[i] != ‘\0’) {
if (sentence[i] == 0x20) {
countSpaces++;
}
i++;
}
return countSpaces;
});

    [/code]

While the second piece compiles, it’s fairly obvious that it doesn’t execute. My goal for the day is to get the second piece to work.


#8

Interesting, thanks. Had to do some reading to figure out what to do differently. As it turns out, you’re very close.

If you want a hint: the value that is printed is the address of the block.

If you want the answer, post back here, otherwise I’ll let you continue to research it.


#9

I think I’m really missing something basic, I almost want the answer just to save the time, although it’s sometimes through frustration you learn the best. Can you aim me towards the documentation you read that gave you the best clue. Thanks


#10

I realized what was missing while reviewing the documentation I read (Apple’s block documentation, primarily focusing on the “Using Blocks” section, http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/bxUsing.html). Unfortunately, I can’t find what triggered it for me. The necessary fix is very subtle.

I’ll leave it to you to decide when you’re tired of reading docs: if you go to http://www.mobilefish.com/services/rot13/rot13.php and specify Rot47, you can translate the answer below.

yFDE 255 A2C6?E96D6D 2E E96 6?5 @7 E96 3=@4< :?G@42E:@?i AC:?E7W]]]][ /L ]]] NWXX


#11

Impressed, I would have spent the rest of the night looking and probably never stumbled upon that as the resolution. It does seem logical in retrospect, but I wouldn’t have arrived at that answer.

Thanks,


#12

Yeah, it was probably more my quasi-familiarity with function pointers than anything else that led me to the right answer. As you said, logical in retrospect, but tough to pick out from all the syntactic noise with blocks.

Thanks for adding this to your challenge and posting about it here; it was a good excuse to learn a bit more.


#13

Hi there,

here is my go at it. The only thing remarkable is the “missing” brackets.

In this case they could be left out because:

  1. There is only one line in the if-block, so no brackets are needed.
  2. The while statement itself consists only of one element (the if-block which includes the numberOfSpaces++) and does not need brackets, too.

[code]
int spaceCount(const char *c)
{
int numberOfSpaces = 0, i = 0;

while(c[i])
	if(c[i++] == ' ')
		numberOfSpaces++;

return numberOfSpaces;

}[/code]

Ususally I would to brackets, though, because they tend to improve code readability.

Happy coding

iFlash


#14

Here is my function, which seems to be about what everyone has:int spaceCount(const char *sentence) { int count = 0; for (int i = 0; sentence[i] != '\0'; i++) { if (sentence[i] == ' ') { count++; } } return count; }but I got the following warnings: “Implicit declaration of function ‘spaceCount’ is invalid in c99”, and, “No previous prototype for function ‘spaceCount’”. The first warning I solved by physically placing the function before ‘main’. The second warning I solved by placing the function prototype int spaceCount(const char *sentence); before the actual function (just below the header). I know most people here are smarter than that but I figure there might be someone who could benefit from my efforts, as I have benefitted greatly from all of yours!


#15

My solution isn’t working, I get "Expected “;” at end of declaration on the line “int spaceCount…”

Functions declarations don’t require this so I’m not sure what is going on.

#include <stdio.h>

int main(int argc, const char * argv[])
{

    const char *sentence = "He was not in the cab at the time.";
    
    
    int spaceCount(const char *sentence)
    {
        int c = 0;
        for (i=0; i < strlen *sentence; i ++)
            if (sentence[i] == 0x20) {
                c=++;
            }
        
    }
    return c;
    
    
    printf("\"%s\" has %d spaces\n", sentence, spaceCount(sentence));
        
    
    
    return 0;
}

#16

A function is declared outside of main and before it is called.

The prototype warning can be turned off but I prefer to use them.
This should work a little better.

[code]#include <stdio.h>
#include <string.h> // Declares strlen()

// Prototype

int spaceCount(const char *sentence);

//Function.  If a prototype is used then this function can be placed after the main function.

int spaceCount(const char *sentence)
{
int c = 0;
for (int i=0; i < strlen(sentence); i++)
if (sentence[i] == 0x20) {
c++;
}
return c;

}

int main(int argc, const char * argv[])
{

const char *sentence = "He was not in the cab at the time.";

printf("\"%s\" has %d spaces\n", sentence, spaceCount(sentence));

return 0;

}
[/code]
Mitch


#17

My solution:

[code]int spaceCount(const char *s);

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
	const char *sentence = "He was not in the cab at the time.";
	printf("\"%s\" has %d spaces\n", sentence, spaceCount(sentence));

}
return 0;

}

int spaceCount(const char *s)
{
char c;
int count = 0;
while ((c = *s++)) {// !=’\0’ is implied
if (c == 32) {
count++;
}
}
return count;
}[/code]


#18
int compterEspace( char * s){
    int nb=0 ;
    while(*s) 
        nb=(*s++ == ' ') ? ++nb : nb ;
    return nb ;
}

some explanations :
when *s == ‘\0’ *s is evaluated at zero, this means ‘\0’, this means NULL, this means FALSE.
The ternary operator compare *s to space, postincrement s, return the preincremented nb variable if == space or nb if not
and affect the result to nb.

Yes, we can omit the ternary operator with

if (*s++==' ') ++nb ;

but I like the ternary operator !


#19

My solution using bloc :

[code]
@autoreleasepool {

    int(^compterEspaces)(const char*);
    
    compterEspaces = ^(const char *test) {
        
        int compteur = 0;
        int i =0;
        
        while(test[i]!='\0') {
            
            if(test[i] == ' ')
                compteur++;
            
            i++;
            
        }
        
        return compteur;
        
    };

    const char *phrase = "Portez ce vieux Whisky au juge blond qui fume.";
        
    printf("\"%s\" comprend %d espaces.\n",phrase, compterEspaces(phrase));
    
}

return 0;

}[/code]