字符串数组打印出垃圾值

时间:2017-01-25 13:51:15

标签: c

所以我有一个分配,如果字符在字符串中有重复,我应该删除它。现在它可以做到,但也会在最后打印出垃圾值。我不知道为什么会这样,所以任何帮助都会很好。 我也不确定如何打印出新字符串的长度。

这是我的main.c文件:

#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;
}

printf("%c", string[i]);的输出打印出字符串末尾的垃圾值,这是不正确的。

deleteDuplicates函数在functions.c文件中如下所示:

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++;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

有一种更有效率和更安全的方式来进行锻炼:

#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);
}

您可以在此处查看结果: http://codepad.org/wECjIonL

甚至可以在这里找到更精致的方式: http://codepad.org/BXksElIG

答案 1 :(得分:0)

C中的函数默认是按值传递,而不是按引用传递。因此,deleteDuplicates函数不会修改main函数的长度。如果修改函数以通过引用传递,则将修改您的长度。

以下是使用您的代码的示例。

函数调用将是:

deleteDuplicates(string, &length);

该功能将是:

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++;
            }
        }
    }
}

答案 2 :(得分:0)

您可以通过散列数组中的字符来实现O(n)解决方案。

但是,发布的其他答案将帮助您解决代码中的当前问题。我决定向你展示一种更有效的方法。

您可以像这样创建一个哈希数组:

int hashing[256] = {0};

将数组中的所有值设置为0。然后,您可以检查插槽是否有0,这意味着该角色尚未被访问过。每次找到0时,将字符添加到字符串中,并将该插槽标记为1。这可以保证不会添加重复的字符,因为只有在找到0时才会添加它们。

这是一种在任何地方都使用的常用算法,它将有助于提高代码的效率。

最好使用fgets来读取用户的输入,而不是scanf()

这是我刚才写的一些修改过的代码,它显示了哈希的这个想法:

#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;
}

示例输入:

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

输出:

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