C 字符串数组打印出垃圾值

C 字符串数组打印出垃圾值,c,C,所以我有一个赋值,如果字符串中有重复的字符,我应该删除它。现在它可以这样做,但也会在最后打印垃圾值。我不知道它为什么会这样,所以任何帮助都很好。 我也不知道我应该如何打印出新字符串的长度 这是我的主.c文件: 默认情况下,C中的函数是按值传递的,而不是按引用传递的。因此,deleteDuplicates函数不会修改主函数中的长度。如果将函数修改为通过引用传递,则将修改长度 下面是一个使用您的代码的示例 函数调用将是: deleteDuplicates(string, &length);

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

这是我的主.c文件:


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

下面是一个使用您的代码的示例

函数调用将是:

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++;
            }
        }
    }
}
其职能是:

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

有一种更有效、更安全的方法来做这项工作:

#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);
}
您可以在此处看到结果:

甚至可以在这里找到更精细的方法:

您可以通过对数组中的字符进行散列来实现On解决方案

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

您可以创建如下所示的哈希数组:

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

这是一种普遍使用的算法,它将有助于提高代码的效率

此外,最好使用它来读取用户输入,而不是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;
}
输出:

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

字符串[k+1];将访问越界,导致deleteDuplicates函数中出现未定义的行为此方法效率极低。对字符进行排序或散列不是更好吗?还有,为什么不使用fgets读取字符?为什么不将指针解引用到长度?现在你可以比较iOriginal string: hellotherefriend Length: 16 Duplicates removed: helotrfind Length: 10