【问题标题】:My function goes over the length of string我的函数超过了字符串的长度
【发布时间】:2015-03-27 18:17:46
【问题描述】:

我正在尝试制作将所有字母从字母表与我插入的字符串进行比较的函数,并打印我没有使用的字母。但是当我打印这些字母时,它会过去并在最后给我随机符号。这是函数的链接,我如何调用函数和结果: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▒ˉ

【问题讨论】:

  • getAvailableLetters 似乎有问题;很难说没有看到它的实现是什么(相关代码应该包含在帖子中,而不是链接到)。 (另外:while 循环的意义何在?)最后:学习格式化您的代码的注释!
  • 我尝试正确格式化但失败了:/ 所以我使用了 pastebin。第一次使用本网站
  • 是的,我知道 getAvailableLetters 有问题
  • 也不要介意循环,它只是为了测试
  • 不要像你一样在循环条件中使用strlen();每次循环迭代时都会调用它,这会使您的算法爆炸。您在main() 程序中确定i 何时达到strlen(text) 大小的循环很奇怪;你只需写i = strlen(text);(没有可见的循环)。

标签: c string function overflow


【解决方案1】:

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

【讨论】:

  • 这是一个非常非常基础的问题。请谷歌 printf() 和基本的 C 语言教程。此外,您还没有向我们展示您的 getAvailableLetters() 函数在做什么。
【解决方案2】:

对于%s,printf 在到达空字符 '\0' 时停止打印,因为 %s 期望字符串以空字符结尾,但 result 不以空字符结尾,这就是为什么你会在末尾得到随机符号

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

http://pastebin.com/fCyzFVAF

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      char alphabet[]={'a','b','c', ... ,'x','y','z'}; 不是字符串。它只是一个“char 的数组 26”。

      在 C 中,“string 是一个连续的字符序列,以第一个空字符终止并包括第一个空字符。...”。 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 \0
      

      现在alphabet 是“char 的数组 27”,也是一个 字符串


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

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

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

      2) strlen() 返回类型 size_t。这是一些无符号整数类型。如果lettersGuessed 的长度为0(可能是""),则字符串长度- 1 不是-1,而是一些非常大的数字,因为无符号算术“环绕”并且循环可能永远不会停止。下面是一个简单的解决方案。这个解决方案只会失败是字符串的长度超过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++)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多