• Quick note - the problem with Youtube videos not embedding on the forum appears to have been fixed, thanks to ZiprHead. If you do still see problems let me know.

I HATE string manipulation in C

Almo

Masterblazer
Joined
Aug 30, 2005
Messages
6,846
Location
Montreal, Quebec
void QMag::RemoveWord(u8 wordnum, bool answerquote)
{
char worktext[QMAG_MAX_QUOTE_LENGTH];
char* charpoint;
char* charpoint2;
int wordcount = 0;
int wordlen = 0;
int extrachar = 1;

if(answerquote)
{
strcpy(worktext, m_answerText);
}
else
{
strcpy(worktext, m_poolText);
}

charpoint = worktext;

while(*charpoint != '\0' && wordcount < wordnum) // find first char of word to remove
{
while(*charpoint != ' ' && *charpoint != '\0')
{
charpoint++;
}
wordcount++;
if(*charpoint == ' ')
{
charpoint++;
}
else
{
return;
}
}

charpoint2 = charpoint;
while(*charpoint2 != ' ' && *charpoint2 != '\0') // find length of word to be removed
{
wordlen++;
charpoint2++;
}

if(*charpoint2 == '\0') // check if removing last word; extrachar = 1 means there's a trailing space to keep
{
extrachar = 0;
}

while(*(charpoint + wordlen + extrachar) != '\0')
{
*charpoint = *(charpoint + wordlen + extrachar);
charpoint++;
}
if(extrachar == 0) // remove trailing space if at end of string
{
charpoint--;
}
*charpoint = '\0';
if(answerquote)
{
strcpy(m_answerText, worktext);
}
else
{
strcpy(m_poolText, worktext);
}
}

Subtle bug in here is causing it to fail when removing the only word from a one-word string. This is driving me crazy. Don't worry about trying to help, I'm just venting. I suspect string manipulation in C is horrible because Dennis Kenighan who helped design C is the K in AWK, which works fine once you know how to use it. Why put good string stuff in C when any C programmer can just use AWK?

:(
 
Last edited:
Oy, it's been a looooong time since I've dealt with strings in C or C++. I've been using VB and C# for so long, I forget how dang inconvenient the whole thing was!

I remember trying to reference MFC in small projects, just so I could use CString. But, that was before I worked professionaly, and was just fooling around with gunk.

I work with someone who knows C quite well. If there is time, I might just have him look at your code. I sure don't feel like doing so, at the moment, myself. Especially when there's pointers involved.

Never could stand pointers.
 
Last edited:
I appreciate the thought, but it's fixed. But I don't know why since my change was to fix a different problem in InsertWord. :boggled: Glad to know I'm not the only programmer who finds pointers annoying. I guess there's a reason MacOS was written in PASCAL up through System 7. :eye-poppi
 
Last edited:
They were designed to be fast. Period.

So was the Unix case-sensitive file system.

Both are the Devil's work.

~~ Paul

The latter is a nuisance, for sure, but few things have caused quite so many security flaws as a data structure that allows you to write past the end of the allocated memory. Can you say "buffer overflow"? I knew you could.
 
Ummm... Write a tiny subroutine in a string-friendly language, then compile that into a linkable library and call it??? Sheesh - we were doing exactly that 25-30 years ago on VMS to solve precisely this problem...
 
Last edited:
Code:
void QMag::RemoveWord(u8 wordnum, bool answerquote)
{
    char worktext[QMAG_MAX_QUOTE_LENGTH];
    char* charpoint;
    char* charpoint2;
    int wordcount = 0;
    int wordlen = 0;
    int extrachar = 1;

    if(answerquote)
    {
        strcpy(worktext, m_answerText);
    }
    else
    {
        strcpy(worktext, m_poolText);
    }

    charpoint = worktext;

    while(*charpoint != '\0' && wordcount < wordnum) // find first char of word to remove
    {
        while(*charpoint != ' ' && *charpoint != '\0')
        {
            charpoint++;
        }
        wordcount++;
        if(*charpoint == ' ')
        {
            charpoint++;
        }
        else
        {
            return;
        }
    }

    charpoint2 = charpoint;
    while(*charpoint2 != ' ' && *charpoint2 != '\0') // find length of word to be removed
    {
        wordlen++;
        charpoint2++;
    }

    if(*charpoint2 == '\0') // check if removing last word; extrachar = 1 means there's a trailing space to keep
    {
        extrachar = 0;
    }

    while(*(charpoint + wordlen + extrachar) != '\0')
    {
        *charpoint = *(charpoint + wordlen + extrachar);
        charpoint++;
    }
    if(extrachar == 0) // remove trailing space if at end of string
    {
        charpoint--;
    }
    *charpoint = '\0';
    if(answerquote)
    {
        strcpy(m_answerText, worktext);
    }
    else
    {
        strcpy(m_poolText, worktext);
    }
}
Subtle bug in here is causing it to fail when removing the only word from a one-word string. This is driving me crazy. Don't worry about trying to help, I'm just venting. I suspect string manipulation in C is horrible because Dennis Kenighan who helped design C is the K in AWK, which works fine once you know how to use it. Why put good string stuff in C when any C programmer can just use AWK?

:(

Why are you using C strings in a C++ program? Why not use the STL String support?
 
Ummm... Write a tiny subroutine in a string-friendly language, then compile that into a linkable library and call it??? Sheesh - we were doing exactly that 25-30 years ago on VMS to solve precisely this problem...

We are programming on the Nintendo DS. Everything needs to be kept as small and fast as possible. Slow processor, 4 MB RAM. Game programming is different, guys.
 
Last edited:
Aaah! New information on requirements helps!

Write your own small "helper" routines in C that work as required. Optimise the hell out of them. Call them.
 
Well, if it helps, it looks to me as though in the case where there's only one word, and you call with wordnum=1, the routine will exit at the first 'return' statement.

Code:
    while(*charpoint != '\0' && wordcount < wordnum) // find first char of word to remove
    {
        while(*charpoint != ' ' && *charpoint != '\0')
        {
            charpoint++;
        }
        wordcount++;
        if(*charpoint == ' ')
        {
            charpoint++;
        }
        else
        {
            return;  <<--- exit here, for one word
        }
    }

It also looks like that loop is always stepping over the first word; does the function ever work to remove the first word?

(Sorry, I'm fighting off a headache right now, normally I'd be able to do this, honest!)
 
Last edited:
I would suggest that you move the logic that decides which destination string to put the result in out of the function and make it a generic function that just modifies the string it is passed in-place.

Something like this:

Code:
void wordremove(char *s, short n)
{
    char *a = s;
    short i = 1;

    while(*s != '\0')
    {
        if(*s == ' ')
            i++;

        if(i == n)
        {
            while(*++a != ' ' && *a != '\0');

            if(i == 1 && *a != '\0')
                *a++;

            do
                *s++ = *a;
            while(*a++ != '\0');
            
            return;
        }

        *a++, *s++;
    }
}
The use should be fairly obvious, but here's an example:

Code:
char *test = malloc(24);
sprintf(test, "this is my test string.");

wordremove(test, 5);
puts(test);
 
Last edited:
tsg said:
The latter is a nuisance, for sure, but few things have caused quite so many security flaws as a data structure that allows you to write past the end of the allocated memory. Can you say "buffer overflow"? I knew you could.
The source of buffer overflows isn't specifically NUL-terminated strings, because no one uses such a string for a buffer, do they? They either have the buffer length stored in a separate word, or they have the length glued in the code. Either way they can check the length. I assumed the cause was sheer laziness.

~~ Paul
 
LostAngeles said:
I'm learning C++. It's the same, except it's a 5 year old. Your pain is felt.
Actually, it's an additional 2-year-hold hung on the side of the 3-year-old. And you know that the maturity of a 3-year-old plus the maturity of a 2-year-old does not equal the maturity of a 5-year-old.

~~ Paul
 

Back
Top Bottom