pg-robban
pg-robban

Reputation: 1435

Iterating over string/strlen with umlauted characters

This is a follow-up to my previous question . I succeeded in implementing the algorithm for checking umlauted characters. The next problem comes from iterating over all characters in a string. I do this like so:

int main()
{
    char* str = "Hej du kalleåäö";
    printf("length of str: %d", strlen(str));

    for (int i = 0; i < strlen(str); i++)
    {
        printf("%s ", to_morse(str[i]));
    }
    putchar('\n');
    return 0;
}

The problem is that, because of the umlauted characters, it prints 18, and also makes the to_morse function fail (ignoring these characters). The toMorse method accepts an unsigned char as a parameter. What would be the best way to solve this? I know I can check for the umlaut character here instead of the letterNr function but I don't know if that would be a pretty/logical solution.

Upvotes: 1

Views: 1240

Answers (4)

Evan Teran
Evan Teran

Reputation: 90543

EDIT: What locale are you using?

If you are going to iterating over a string, don't bother with getting its length with strlen. Just iterate until you see a NUL character:

char *p = str;
while(*p != '\0') {
    printf("%c\n", *p);
    ++p;
}

As for the umlauted characters and such, are they UTF-8? If the string is multi-byte, you could do something like this:

size_t n = strlen(str);
char *p = str;
char *e = p + n;
while(*p != '\0') {
    wchar_t wc;
    int l = mbtowc(&wc, p, e - p);
    if(l <= 0) break;
    p += l;
    /* do whatever with wc which is now in wchar_t form */
}

I honestly don't know if mbtowc will simply return -1 if it encounters a NUL in the middle of a MB character. If it does, you could just pass MB_CUR_MAX instead of e - p and do away with the strlen call. But I have a feeling this is not the case.

Upvotes: 0

diciu
diciu

Reputation: 29343

On OS X, Cocoa is a solution - note the use of "%C" in NSLog - that's an unichar (16-bit Unicode character):

#import <Cocoa/Cocoa.h>

int main()
{
        NSAutoreleasePool * pool = [NSAutoreleasePool new];
        NSString * input = @"Hej du kalleåäö";

        printf("length of str: %d", [input length]);
        int i=0;
        for (i = 0; i < [input length]; i++)
        {
                NSLog(@"%C", [input characterAtIndex:i]);
        }

        [pool release];
}

Upvotes: 1

Lucas
Lucas

Reputation: 14129

You could do something like

for (int i = 0; str[i]!='\0'; ++i){
    //do something with str[i]
}

Strings in C are terminated with '\0'. So it is possible to check for the end of the string like that.

Upvotes: 0

Carl Smotricz
Carl Smotricz

Reputation: 67820

Normally, you'd store the string in a wchar_t and use something like ansi_strlen to get the length of it - that would give you the number of printed characters as opposed to the number of bytes you stored.

You really shouldn't be implementing UTF or Unicode or whatever multibyte character handling yourself - there are libraries for that sort of thing.

Upvotes: 3

Related Questions