我的函数超出了字符串的长度

My function goes over the length of string

我正在尝试制作一个函数来比较字母表中的所有字母和我插入的字符串,并打印我没有使用的字母。但是当我打印这些字母时,它会结束并在最后给我随机符号。这是 link 函数,我如何调用函数和结果:http://imgur.com/WJRZvqD,U6Z861j,PXCQa4V#0

代码如下:(http://pastebin.com/fCyzFVAF)

void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
        char alphabet[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
        int LG,LG2,LA=0;
        for (LG=0;LG<=strlen(alphabet)-1;LG++)
        {
                for(LG2=0;LG2<=strlen(lettersGuessed)-1;LG2++)
                {
                        if (alphabet[LG]==lettersGuessed[LG2])
                        {
                                break;
                        }
                        else if(alphabet[LG]!=lettersGuessed[LG2] &&LG2==strlen(lettersGuessed)-1)
                        {
                                availableLetters[LA]=alphabet[LG];
                                LA++;
                        }
                }
        }
}

调用函数的程序如下:

#include <stdio.h>
#include <string.h>
#include "hangman.c"

int main() 
{
    int i = 0;
    char result[30];
    char text[30];
    scanf("%s", text);

    while(i != strlen(text))
    {
        i++;
    }

    getAvailableLetters(text, result);
    printf("%s\n", result);
    printf ("%d", i);
    printf ("\n");
}

这是我输入 abcd 时的结果:efghijklmnopqrstuvwxyzUw▒ˉ

如果要将 result 打印为字符串,则需要在其末尾包含一个终止空值(这就是 printf 知道何时停止的方式)。

确保您的字符串以 NULL 结尾(例如,末尾有一个“\0”字符)。这也意味着确保保存字符串的缓冲区足够大以包含空终止符。

有时人们认为他们有一个空终止字符串,但该字符串在内存中溢出了边界并截断了空终止符。这就是您总是希望使用读取数据的函数形式(在这种情况下不适用)的原因,例如应该调用 snprintf() 的 sprintf() 以及可以写入缓冲区的任何其他函数成为让您明确限制长度的形式,这样您就不会被病毒或漏洞严重攻击。

for %s printf 在到达空字符 '[=11=]' 时停止打印,因为 %s 期望字符串以空字符终止,但 result 不是空字符终止并且这就是为什么你在最后得到随机符号

只需在函数的最后一行添加availableLetters[LA] = '[=14=]' getAvailableLetters

http://pastebin.com/fCyzFVAF

char alphabet[]={'a','b','c', ... ,'x','y','z'}; 不是字符串。它只是一个 "array 26 of char".

In C, "A string is a contiguous sequence of characters terminated by and including the first null character. ...". C11 §7.1.1 1

strlen(alphabet) 需要一个 字符串 。由于代码没有提供字符串,结果未定义。

要修复,请确保 alphabet 字符串

char alphabet[]={'a','b','c', ... ,'x','y','z', 0};
// or
char alphabet[]={"abc...xyz"};  // compiler appends a [=10=]

现在 alphabet 是 "array 27 of char" 也是一个 字符串 .


第 2 期:for(LG2=0;LG2<=strlen(lettersGuessed)-1;LG2++) 有 2 个问题。

1) 每次循环,代码都会重新计算字符串的长度。最好计算一次字符串长度,因为字符串长度在循环内不会改变。

    size_t len = strlen(lettersGuessed);
    for (LG2 = 0; LG2 <= len - 1; LG2++)

2) strlen() returns 类型size_t。这是一些无符号整数类型。如果 lettersGuessed 的长度为 0(可能是 ""),则字符串长度 - 1 不是 -1,而是一些非常大的无符号算术 "wraps around" 和循环可能永远不会停止。下面是一个简单的解决方案。该解决方案只会在字符串长度超过 INT_MAX.

时失败
    int len = (int) strlen(lettersGuessed);
    for (LG2 = 0; LG2 <= len - 1; LG2++)

没有此限制的解决方案将始终使用 size_t

    size_t LG2;
    size_t len = strlen(lettersGuessed);
    for (LG2 = 0; LG2 < len; LG2++)