In the str char array below I would first like to locate the first math symbol I see, then I would like to count backwards and remove whatever is between the previous three " _ " and remove the three " _ ". Can I please get some ideas on how to do this?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

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

    char str [] = "xa_55_y_*_z_/_+_x_+";
    int length = 0;
    int decrementor = 0;
    int underscore_counter = 0;
    int i = 0;
    length = strlen (str);

    for(i  = 0; i < length; i++)
    {
        decrementor = 0;
        underscore_counter = 0;
        if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
        {
            decrementor = i;
            while(underscore_counter != 3)
            {
                if(str[i] == '_')
                {
                    underscore_counter++;
                }
                decrementor--;
            }
        }
    }

    return 0;
}

Edited 7 Months Ago by COKEDUDE

Since there is no edit button I'm updating my code here.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

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

    char str [] = "xa_55_y_*_z_/_+_x_+";
    int length = 0;
    int decrementor = 0;
    int underscore_counter = 0;
    int i = 0;
    length = strlen (str);

    for(i  = 0; i < length; i++)
    {
        decrementor = 0;
        underscore_counter = 0;
        if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
        {
            decrementor = i;
            while(underscore_counter != 3)
            {
                if(str[decrementor] == '_')
                {
                    underscore_counter++;
                    printf("underscore_counter is %d \n", underscore_counter);
                }
                decrementor--;
            }
        }
    }

    return 0;
}

If I am reading this correctly, the goal is to change the string "xa_55_y_*_z_/_+_x_+" to "xa*_z_/_+_x_+". You want to strip out "_55_y_", which is indexes 2 through 7 of the string? When you are done with the while loop on lines 23 to 31, i should equal 8 and decrementor should equal 2? Assuming I am correct in my interpretation, after running your code, i will equal 8 and decrementor equal 1 when you finish with your while loop. An easy fix would be to move the decrementor-- line at line 30 to be the TOP line of your while loop, like so. Your while loop would be this:

        while(underscore_counter != 3)
        {
            decrementor--;
            if(str[decrementor] == '_')
            {
                underscore_counter++;
                printf("underscore_counter is %d \n", underscore_counter);
            }
        }

Your code correctly finds the underscore indexes at indexes 7, 5, and 2. Line 30 of your original code will decrement decrementor from 2 to 1. Changing that line to be at the top of the while loop will keep the value of decrementor at 2, which I believe is what you want. Now that you have found your relative indexes at 2 and 8, you want to strip the string and you want to stop looking for underscores and math operators. I propose that have a flag variable that is flagged as true once you have found the math operator. Check that flag as you iterate through the string. If the flag is set, you have found the relative indexes and you want to now strip characters from the string. I am assuming that you are not allowed to use a function like memmove or any other function from string.h to help you strip the string? If you can, use it, but it's easy enough to simply continue iterating through the string. However, this time, you'll simply be moving characters one by one to an index six characters earlier (i minus decrementor, or 8 - 2 = 6). I suggest a new variable called offset. Declare it at the top. So your code is now this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>  // needed for the operator_found variable

int main(int argc, char *argv[])
{
    bool operator_found = false;
    int offset;
    char str [] = "xa_55_y_*_z_/_+_x_+";
    int length = 0;
    int decrementor = 0;
    int underscore_counter = 0;
    int i = 0;
    length = strlen (str);

    for(i  = 0; i < length; i++)
    {
        decrementor = 0;
        underscore_counter = 0;
        if(!operator_found && (str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-'))
        {
            operator_found = true;
            decrementor = i;
            while(underscore_counter != 3)
            {
                decrementor--;
                if(str[decrementor] == '_')
                {
                    underscore_counter++;
                    printf("underscore_counter is %d \n", underscore_counter);
                }
            }

            offset = i - decrementor; // 8 - 2 = 6
        }

        if(operator_found)
        {
            // string stripping code goes here.  Use the offset variable
            str[i - offset] = str[i];
        }
    }

    return 0;
}

If you run the program as-is, you'll notice that if you print the string, six indexes have been stripped out, but it is too long now:

"xa*_z_/_+_x_+_+_x_+". You have an extra "_+_x_+" at the end. That's because the NULL terminator was not moved. Easy enough to fix. Change your loop control code from < to <= like so at the top:

Change for(i = 0; i < length; i++) to this: for(i = 0; i <= length; i++).

Note that your code contains no code that checks to make sure that decrementor does not become negative. Thus your program could crash if you end up with a string like "xa55_y_*_z_/_+_x_+" or any other string where there are not at least three underscores before the first arithmetic operator.

Edited 7 Months Ago by AssertNull: Automatic parsing was not parsing correctly

This article has been dead for over six months. Start a new discussion instead.