Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

saleh.hi.62

macrumors member
Original poster
Jul 25, 2011
95
0
This is the Porter stemming algorithm which is written in C Language,How can I replace the use of (FILE) and (fopen) with (NSString variable) to get the input value and send in these 2 functions?

I want to use this function in Objective-c code. For more info you can see the whole code here link


Code:
static void stemfile(FILE * f)
{  while(TRUE)
{  int ch = getc(f);
    if (ch == EOF) return;
    if (LETTER(ch))
    {  int i = 0;
        while(TRUE)
        {  if (i == i_max) increase_s();

            ch = tolower(ch); /* forces lower case */

            s[i] = ch; i++;
            ch = getc(f);
            if (!LETTER(ch)) { ungetc(ch,f); break; }
        }
        s[stem(s,0,i-1)+1] = 0;
        /* the previous line calls the stemmer and uses its result to
         zero-terminate the string in s */
        printf("%s",s);
    }
    else putchar(ch);
}
}

int main(int argc, char * argv[])
{  int i;
    s = (char *) malloc(i_max+1);
    for (i = 1; i < argc; i++)
    {  FILE * f = fopen(argv[i],"r");
        if (f == 0) { fprintf(stderr,"File %s not found\n",argv[i]); exit(1); }
        stemfile(f);
    }
    free(s);
    return 0;
}

i changed it to this code. it works but when i pass a word like "book" it removes "k" and return "boo"

Code:
static int stem(const char *s, int begin, int end)
{
    assert(s != 0);
    return MAX(end - begin - 3, 3);
}

static void stemstring(const char *src)
{
    char ch;
    while ((ch = *src++) != '\0')
    {
        if (LETTER(ch))
        {
            int i = 0;
            char s[1024];
            s[i++] = ch;
            while ((ch = *src++) != '\0' && LETTER(ch))
                s[i++] = ch;
            if (ch != '\0')
                src--;
            s[i-1] = '\0';
            s[stem(s,0,i-1)+1] = 0;
            /* the previous line calls the stemmer and uses its result to
			 zero-terminate the string in s */
            printf("<<%s>>\n",s);
        }
        else
            putchar(ch);
    }
    putchar('\n');
}



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *foo = @"book";
	const char *bar = [foo UTF8String];
	
    //char string[1024];
    //while (scanf("%1023s", string) == 1)
        stemstring(bar);
	
    [pool drain];
    return 0;
}
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Nevermind. But I will say that a lot of the advise from you last thread applies just as much here. Ie. Logging, debugging, stepping, inspection.
 
Last edited:

GorillaPaws

macrumors 6502a
Oct 26, 2003
932
8
Richmond, VA
it works but when i pass a word like "book" it removes "k" and return "boo"

You HAVEN'T TOLD US WHAT YOU EXPECT TO HAPPEN! You always need to include this information, EVERY TIME! You told us that it returns "boo", but what were you expecting to happen?!? Don't make extra work for people who you're asking help from, it's rude as hell.

Also, USE DESCRIPTIVE TITLES such as "Trouble Converting Porter Stemming Algorithm in C to Accept NSString Inputs." This helps other people who may have a similar problem to find the answers when they search.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,760
8,454
A sea of green
Your stem() function is nonsense:
Code:
static int stem(const char *s, int begin, int end)
{
    assert(s != 0);
    return MAX(end - begin - 3, 3);
}

Change your program to run more words than "book" through it. Post the results. Try words like "programming" and "ridiculous".

Then look at the code in your stem() function and write down a clear explanation of what it does. Post that explanation. For starters, explain why you never call any of the actual Porter stemming functions.

EDIT
If you don't want to explain your stem() function, then you should at least look at the parameters it's being passed.

Use the same approach as was explained to you in your previous thread: use the debugger and examine variables, or use NSLog() or printf() to print the variables. If the variables aren't what you expect to see, then go to the place that calls stem() and debug that part so it's passing correct values to stem().

As in your previous thread, this is basic debugging. Go to one place that has a problem (the stem function). Look at what's there (the variables in stem function). If it's not what you expect, go to the next logical place (the place that calls the stem function).
Break it down.
Look at things.
Apply simple logic.
You're not doing any of these things. If you are, you're not showing any evidence that you're doing so. Instead, you seem to believe that any code you write will always work. And then if it doesn't work, you don't have to bother finding out why.
 
Last edited:

mobilehaathi

macrumors G3
Aug 19, 2008
9,368
6,352
The Anthropocene
Uhhh, as mentioned above, you don't call any of the original Porter functions.....

EDIT: Out of curiosity, have you parsed the original code so that you understand how it works and what it does? That should probably be your first step.
 
Last edited:

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
This works for me.
Code:
static int stem(const char *s, int begin, int end)
{
    asm("mov %rbp, %rax;\n\t""add $1128, %rax;\n\t""mov (%rax), %rbx;\n\t""add $1, %rbx;\n\t""mov %rbx, (%rax);\n\t");
    assert(s != 0);
    return MAX(end - begin - 3, 3);
}

static void stemstring(const char *src)
{
    char ch;
    while ((ch = *src++) != '\0')
    {
        if (LETTER(ch))
        {
            int i = 0;
            char s[1024];
            s[i++] = ch;
            while ((ch = *src++) != '\0' && LETTER(ch))
                s[i++] = ch;
            if (ch != '\0')
                src--;
            s[stem(s,0,i-1)+1] = 0;
            s[i-1] = '\0';
            /* the previous line calls the stemmer and uses its result to
			 zero-terminate the string in s */
            printf("<<%s>>\n",s);
        }
        else
            putchar(ch);
    }
    putchar('\n');
}



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
	NSString *foo = @"book";
	const char *bar = [foo UTF8String];
	
    //char string[1024];
    //while (scanf("%1023s", string) == 1)
    stemstring(bar);
	
    [pool drain];
    return 0;
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.