Lsm
Lsm

Reputation: 1

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice. Also im not sure how I should print out the length of the new string.

This is my main.c file:

#include <stdio.h>
#include <string.h>
#include "functions.h"

int main() {

    char string[256];
    int length;

    printf("Enter char array size of string(counting with backslash 0): \n");
/*
    Example: The word aabc will get a size of 5.
    a = 0
    a = 1
    b = 2
    c = 3
    /0 = 4
    Total 5 slots to allocate */

    scanf("%d", &length);

    printf("Enter string you wish to remove duplicates from: \n");
    for (int i = 0; i < length; i++)
    {
        scanf("%c", &string[i]);
    }

    deleteDuplicates(string, length);

    //String output after removing duplicates. Prints out trash values!
    for (int i = 0; i < length; i++) {
        printf("%c", string[i]);
    }
    //Length of new string. The length is also wrong!
    printf("\tLength: %d\n", length);
    printf("\n\n");

    getchar();
    return 0;
}

The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.

The deleteDuplicates function looks like this in the functions.c file:

void deleteDuplicates(char string[], int length) 
{
    for (int i = 0; i < length; i++) 
    {
        for (int j = i + 1; j < length;) 
        {
            if (string[j] == string[i]) 
            {
                for (int k = j; k < length; k++) 
                {
                    string[k] = string[k + 1];
                }
                length--;
            }
            else 
            {
                j++;
            }
        }
    }
}

Upvotes: 0

Views: 308

Answers (3)

RoadRunner
RoadRunner

Reputation: 26315

You can achieve an O(n) solution by hashing the characters in an array.

However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.

You can create a hash array like this:

int hashing[256] = {0};

Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.

This is a common algorithm that is used everywhere, and it will help make your code more efficient.

Also it is better to use fgets for reading input from user, instead of scanf().

Here is some modified code I wrote a while ago which shows this idea of hashing:

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

#define NUMCHAR 256

char *remove_dups(char *string);

int main(void) {
    char string[NUMCHAR], temp;
    char *result;
    size_t len, i;
    int ch;

    printf("Enter char array size of string(counting with backslash 0): \n");
    if (scanf("%zu", &len) != 1) {
        printf("invalid length entered\n");
        exit(EXIT_FAILURE);
    }

    ch = getchar();
    while (ch != '\n' && ch != EOF);

    if (len >= NUMCHAR) {
        printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
        exit(EXIT_FAILURE);
    }

    printf("Enter string you wish to remove duplicates from: \n");
    for (i = 0; i < len; i++) {
        if (scanf("%c", &temp) != 1) {
            printf("invalid character entered\n");
            exit(EXIT_FAILURE);
        }
        if (isspace(temp)) {
            break;
        }
        string[i] = temp;
    }
    string[i] = '\0';

    printf("Original string: %s Length: %zu\n", string, strlen(string));

    result = remove_dups(string);

    printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));

    return 0;
}

char *remove_dups(char *str) {
    int hash[NUMCHAR] = {0};
    size_t count = 0, i;
    char temp;

    for (i = 0; str[i]; i++) {
        temp = str[i];
        if (hash[(unsigned char)temp] == 0) {
            hash[(unsigned char)temp] = 1;
            str[count++] = str[i];
        }
    } 

    str[count] = '\0';

    return str;
}

Example input:

Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend

Output:

Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

Upvotes: 0

Carles
Carles

Reputation: 453

There is a more efficent and secure way to do the exercise:

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

void deleteDuplicates(char string[], int *length) 
{
    int p = 1; //current 
    int f = 0; //flag found
    for (int i = 1; i < *length; i++) 
    {
        f = 0;
        for (int j = 0; j < i; j++) 
        {
            if (string[j] == string[i])
            {
                f = 1;
                break;
            }
        }
        if (!f)
            string[p++] = string[i];

    }
    string[p] = '\0';
    *length = p;
}

int main() {
    char aux[100] = "asdñkzzcvjhasdkljjh";
    int l = strlen(aux);

    deleteDuplicates(aux, &l);
    printf("result: %s -> %d", aux, l);
}

You can see the results here: http://codepad.org/wECjIonL

Or even a more refined way can be found here: http://codepad.org/BXksElIG

Upvotes: 1

quickblueblur
quickblueblur

Reputation: 286

Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.

Here's an example using your code.

The function call would be:

deleteDuplicates(string, &length);

The function would be:

void deleteDuplicates(char string[], int *length) 
{
    for (int i = 0; i < *length; i++) 
    {
        for (int j = i + 1; j < *length;) 
        {
            if (string[j] == string[i]) 
            {
                for (int k = j; k < *length; k++) 
                {
                    string[k] = string[k + 1];
                }
                *length--;
            }
            else 
            {
                j++;
            }
        }
    }
}

Upvotes: 0

Related Questions