C 字符串数组打印出垃圾值
所以我有一个赋值,如果字符串中有重复的字符,我应该删除它。现在它可以这样做,但也会在最后打印垃圾值。我不知道它为什么会这样,所以任何帮助都很好。 我也不知道我应该如何打印出新字符串的长度 这是我的主.c文件:C 字符串数组打印出垃圾值,c,C,所以我有一个赋值,如果字符串中有重复的字符,我应该删除它。现在它可以这样做,但也会在最后打印垃圾值。我不知道它为什么会这样,所以任何帮助都很好。 我也不知道我应该如何打印出新字符串的长度 这是我的主.c文件: 默认情况下,C中的函数是按值传递的,而不是按引用传递的。因此,deleteDuplicates函数不会修改主函数中的长度。如果将函数修改为通过引用传递,则将修改长度 下面是一个使用您的代码的示例 函数调用将是: deleteDuplicates(string, &length);
默认情况下,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读取字符?为什么不将指针解引用到长度?现在你可以比较i
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10