In the following program I'M trying to take a number no more than 12 digits long and make it a factor of 3.

If the input is 1, the program would turn the number into 001.
If the input is 12, the program would turn the number into 012.
If the input is 123, the program would simple continue.

The magic should be happening after the second while loop. Can anyone tell me what I'M doing wrong. When I input one digit I get the error "Segmentation fault (core dumped)", when I input two digits it seems to be replacing the first digit with a copy of the second, the only thing it does right is insert the '0' into position[0]. Code is below, thanks.

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "functions.h"

int main(int argc, char *argv[])
{
    if(strlen(argv[1]) % 3 != 0 || strlen(argv[1]) < 3)
    {
        char inputNumber[13];
        char *numberProcessor = inputNumber;

        // insert the char elements from argv[1] into the elements of inputNumber
        char *counter = argv[1];
        while(*counter != '\0')
        {
            *numberProcessor = *counter;

            counter++;
            numberProcessor++;
        }
std::cout << "The inputNumber variable is :" << inputNumber << std::endl;

        // move each elemtn to the right one space and insert a '0' as the first element of inputNumber until the condition fails.
        int backwardCounter = strlen(inputNumber);
        while(strlen(inputNumber) % 3 != 0 || strlen(inputNumber) < 3)
        {
            inputNumber[backwardCounter + 1] = inputNumber[backwardCounter];
            backwardCounter--;

            if(backwardCounter == 0)
            {
                inputNumber[0] = '0';
            }
        }

        std::cout << inputNumber << std::endl;

    }
    else
    {
std::cout << "Number is evenly divisible by 3 " << std::endl;
    }

    return 0;
}

When do you get the segmentation fault? Right away or do you get some output before the segmentation fault? And when you input a 2-digit number, do you get wrong output for both "The inputNumber variable is :" and the result or only the latter?

One problem I see is that you don't 0-terminate inputNumber.

Another problem is that your while loop can cause backwardsCounter to become negative. If strlen(inputNumber) is 1 for example, the following happens:

Your while loop runs for the first time with strlen(inputNumber) and backwardCounter both being 1. It will copy inputNumber[1] (which will be the 0-terminator) to inputNumber[2]. Note that inputNumber[1] still contains the 0-terminator, so strlen(inputNumber) is still 1. You decrement backwardCounter by 1, so it is now 0 and inputNumber[0] is set to '0'.

Now the loop runs a second time with strlen(inputNumber) being 1 and backwardCounter being 0. inputNumber[0] (which is '0' because you just set it to that) is copied to inputNumber[1]. backwardNumber is decremented.

Now backwardNumber is -1 and strlen(inputNumber) is 2, so the loop runs a third time. inputNumber[-1] is copied ... BAM! Segmentation fault!

The only thing that is in functions.h is the prototype for the get_gropus function "int get_groups( int length );".

I input 1 I get the following:

--> The inputNumber variable is: 1
--> Segmentation fault (core dumped)

I input 12 I get the following:

--> The inputNumber variable is: 12
--> 022 (should be 012)

I input 123 I get the following:

--> Number is evenly divisible by 3 (continues as it should)

Okay, so the fact that you don't 0-terminate inputNumber doesn't seem to bite you here (presumably because the unitialized elements of inputNumber happens to be 0 on your system). You should definitely still do that though - something as trivial as adding a function call to your code might break it.

The problems you are encountering seem to be the result of the second problem that I described.

Here's some code you might find interesting. This routine will pad the input number with the required number of '0's to make the length divisible by 3:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string input = "";
    while(true)
    {

        cout <<"Enter number('Q' to quit): ";
        getline(cin,input);
        if(input == "Q" || input == "q")
            break;
        for(int i=0; i<strlen(input.c_str()) % 3; i++)
        {
            input = "0" + input;
        }
        cout << input << endl << endl;
    }
    return 0;
}

sepp2k, I will look at what you described and see what I can come up with. It takes every neuron I have to attempt working with array+pointers.

tinstaafl, Thanks but I have been told not to use the string class, or classes at all for that matter. I have to do this using C-style strings.

Since you're using strlen I assume C string functions are OK. Take a look at this:

#include <iostream>
#include <string.h>
using namespace std;
int main()
{
    char input[100] = "";
    char pad[100] = {"0"};
    while(true)
    {    
        cout <<"Enter number('Q' to quit): ";
        cin >> input;
        if(strcmp(input,"Q") == 0 || strcmp(input,"q") == 0)
            break;
        for(int i=0; i<strlen(input) % 3; i++)
        {                
            strcat(pad,input);
            strcpy(input,pad);
            strcpy(pad,"0");

        }
        cout << input << endl << endl;
    }
    return 0;
}

Edited 3 Years Ago by tinstaafl

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