【问题标题】:Variables are overwritten in C [closed]变量在C中被覆盖[关闭]
【发布时间】:2017-11-11 12:15:50
【问题描述】:

我在 C 中有这个功能:

void convertXY(int* x, int* y, char entry[3]);

Tihs 函数接收两个指向 x 和 y 的指针以及一个字符数组。该条目包含一些像这样的坐标:'a7'、'h13'、'b9'、'd11',并且必须将字母转换为整数 (x),数字也相同。 例如,如果条目是 'h13',x 将为 8,y 为 13。

这是我的函数的完整代码:

void convertXY(int* x, int* y, char entry[3])
{
    int i;
    char alphabet[26] = "abcdefghijklmnopqrstuvwxyz";

    if(entry[2] == NULL) // if the entry is something like 'a1' we must change it to 'a01'
    {
        entry[2] = entry[1];
        entry[1] = '0';
    }

    for(i = 0; i < 26; i++) // we convert the letter into a number
    {
        if (alphabet[i] == entry[0])
            *y = i;
    }

    *x = charToInt(entry[1]) * 10 + charToInt(entry[2]); // we convert entry[1] and entry[2] from char to int using powers of 10 (10^0 and 10^1).
}

还有我的charToInt 函数:

int charToInt(char character)
{
    int i;
    char numbers[10] = "0123456789";

    for(i = 0; i < 10; i++)
        if(numbers[i] == character)
            return i; 
}

问题是当我使用这个函数时,我的一些变量被覆盖了。我不知道为什么会这样。例如:

int variable = 99, x, y;
char entry[3];

printf("variable:%d\n",variable); // prints 99

scanf("%s", &entry);

convertXY(&x, &y, entry);

printf("variable:%d\n",variable); // prints a random number

【问题讨论】:

  • scanf("%s", &amp;entry); => scanf("%2s", entry);entry 是什么?如果是 100,则为未定义的行为。 entry中没有足够的空间@
  • 请停止计数。除非您有 RAM 受限的嵌入式环境,否则只需将 [128] 声明为此类临时缓冲区的最小值。
  • 旁注:有27个字符是"abcdefghijklmnopqrstuvwxyz"(最后一个是'\0',又名空字符)。同理,"0123456789"中有11个字符。
  • 您也可以声明char numbers[10] = {'0','1','2','3','4','5','6','7','8','9'},它确实会分配一个10个字符的数组,但是您将无法对该数组执行任何字符串操作(例如,strlenstrcpy , printf"%s" 等)。
  • @goodvibration 问题中的代码还将分配一个包含 10 个元素的数组。没有附加到数组的尾随终止符。这如何防止调用数组上的字符串函数?一般建议:编写人类可读代码。

标签: c pointers char


【解决方案1】:

如果要存储3个字符,其中\0存储必须是char entry[4]。否则它是未定义的行为。

您不想检查NULL。你想知道的是它的长度是否为 2。

if(strlen(entry)==2) // if the entry is something like 'a1' we must change it to 'a01'
    {
        entry[2] = entry[1];
        entry[1] = '0';
    }

charToInt 如果您知道 ascii 值,就这么简单。我根据上下文将函数名称更改为更合适。

int digitToInt(char digit)
{
      if( digit <= '9' && digit >= '0') 
      return c-'0';
      return -1;
}

字母到整数的转换也是如此。如果你知道它总是在 az 之间,那么你可以这样做:-

void convertXY(int* x, int* y, char entry[3])
{


    if(strlen(entry) == 2) // if the entry is something like 'a1' we must change it to 'a01'
    {
        entry[3]='\0';
        entry[2] = entry[1];
        entry[1] = '0';
    }

    *y = (entry[0]-'a')+1;
    *x = (entry[1]-'0') * 10 + (entry[2]-'0'); // we convert entry[1] and entry[2] from char to int using powers of 10 (10^0 and 10^1).
}

variable命名我会说很糟糕-我从未遇到过将变量命名为variable的代码)是一个局部变量,您想以某种方式更改它是因为@ 987654332@,然后您可以传递地址 o 变量,或者在完成调用函数后使用 xy 的更改值来反映变量 variable

【讨论】:

  • @PaulOgilvie.: 是的..我编辑了
  • 这行得通,我忘记了最后一个 \0 字符。感谢您的回答。而且我不知道 ascii 值,所以我不知道转换这么简单!
  • @Drakalex.:拿一本好书读一读。它会帮助你。放一个有意义的变量名
  • 对于变量名,我更改了它,所以它表明它只是一个变量,我认为它比保留真实名称更简单,这将脱离上下文。我从不在我的代码中命名任何变量varialbe
  • @Drakalex.: 你可以在这里发布原始名称..即使我们不了解上下文..看起来不错。
猜你喜欢
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 2020-01-20
  • 2017-02-25
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
相关资源
最近更新 更多