Home > Software engineering >  Functions change outputs depending on whether I call both or just one
Functions change outputs depending on whether I call both or just one

Time:01-13

I am learning C for the first time after being way more familiar with java and for this program it needs two lines of input for a deck of cards and it will say how many of the cards in a row are of the same suit and how many are in ascending order.

My problem is I think I have both of my functions working and they seem to work independently but when I try to run both of them and then output both answers it either displays nothing or instead of 5 will say 1118234.

I'm also not sure why I get a segmentation fault when I comment out the for loop in main, but with the for loop it works... except that it doesn't use the counter correctly? I am not sure where to start and would appreciate any help!

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

const int DECKSIZE = 52;

int sameSuitCount(char firstHalf[DECKSIZE], char secondHalf[DECKSIZE]);
int ascendingCount(char firstHalf[DECKSIZE], char secondHalf[DECKSIZE]);

int main() {
    int numTests = 0, sameSuit = 0, ascending = 0;
    scanf("%d", &numTests);

    for (int i = 0; i < numTests; i  ) {
        char first[DECKSIZE 1];
        scanf("%s", first);

        char second[DECKSIZE 1];
        scanf("%s", second);

        sameSuit = sameSuitCount(first, second);
        ascending = ascendingCount(first, second);
        printf("\n%d\n", sameSuit);
        printf("\n%d", ascending);
        
    }

    return 0;
}

int sameSuitCount(char firstHalf[DECKSIZE], char secondHalf[DECKSIZE]) {
    int count = 1, max = 0;
    strcat(firstHalf, secondHalf);
    for (int i = 3; i < (DECKSIZE*2); i  = 2){
        //printf("\n%c", firstHalf[i]);
        if(firstHalf[i] == firstHalf[i-2]) {
            //printf(" is the same as %c", firstHalf[i-2]);
            count  ;
            //printf(". Count = %d", count);
        }
        else {
            if (count > max){
            //printf("\nSetting max to %d", count);
            max = count;
            //printf(". Max = %d", max);
            }
            count = 1;
            //printf("Count reset to %d", count);
        }
    }
    return max;
}

int ascendingCount(char firstHalf[DECKSIZE], char secondHalf[DECKSIZE]){
    int count = 1, max = 0;
    strcat(firstHalf, secondHalf);
    for (int i = 0; i < (DECKSIZE*2); i  = 2){
        //printf("\n%c", firstHalf[i]);
        if( !isdigit(firstHalf[i])) {
            //printf(" is not a digit");
            switch(firstHalf[i]) {
                case 'T':
                    firstHalf[i] = 58;
                    break;
                case 'J':
                    firstHalf[i] = 59;
                    break;
                case 'Q':
                    firstHalf[i] = 60;
                    break;
                case 'K':
                    firstHalf[i] = 61;
                    break;
                case 'A':
                    firstHalf[i] = 62;
                    break;
            }
        }
        if( firstHalf[i] == (firstHalf[i-2]   1)   ) {
            //printf(". Is ascending %c", firstHalf[i-2]);
            count  ;
        }
        else if (firstHalf[i] == 50 && firstHalf[i-2] == 62) {
            //printf(". Is ascending %c", firstHalf[i-2]);
            count  ;
        }
        else {
            if (count > max){
            max = count;
            }
            count = 1;
        }
    }
    return max;
}

Sorry for all the printf's littered around trying to debug also.

CodePudding user response:

You misunderstand how strcat works.

It does not allocate any memory, it only copies from one array to another.
It is also a dangerous function, because in C, strings are just arrays of characters, and they are passed to strcat as pointers, so it can not know how big the arrays are.

C arrays are not objects like Java arrays and don't contain information about their size at runtime.

So, when you do this:

strcat(firstHalf, secondHalf);

What happens is the function searches for the fist null character (\0) in firstHalf, then starts copying contents of secondHalf starting with that memory position.

It will continue copying until it finds a null character in secondHalf, even if it runs out of memory in firstHalf.

It will just keep clobbering whatever memory is next, with unpredictable results.

That is why sometimes you get segfault and sometimes random data.

You need to do something like this:

char temp[(DECKSIZE*2)   1];
strncpy(temp, fistHalf, sizeof(temp));
strncat(temp, secondHalf, sizeof(temp));

This way you are guaranteed to have enough memory, and using strncat makes sure no matter what this memory will not be exceeded.

That is what the third parameter is for - it tells the function the maximum number of bytes that can be copied in case null character is not found.

Also, since you pass these arrays by pointer, ascendingCount will modify the original array!

That is why you have different behavior when calling both functions in a row.
There is no way in C to pass strings by value, so if you will probably want to use a temporary array for the modifications if you do not want to loose the original input between function calls.

  •  Tags:  
  • Related