无法理解以下代码中的scanf()行为

时间:2014-12-16 07:19:37

标签: c arrays printf scanf

输入 -

COMETQ
HVNGAT

这是代码 -

#include <stdio.h>
#include <stdlib.h>

#define MAXLEN 6

main(void)
{
    char comet[MAXLEN], group[MAXLEN];
    unsigned long int result[2] = { 1,1 };
    short int i, j;

    scanf("%s",comet);
    scanf("%s",group);
    printf("\nComet's Name: %s\nGroup's Name: %s",comet,group);
    printf("\nComet's No.: %ld\nGroup's No.: %ld",result[0],result[1]);

    i = j = 0;
    while(comet[i]!='\0' && i<MAXLEN){
        result[0] *= (comet[i] - 'A' + 1);
        i++;
    }
    while(group[j]!='\0' && j<MAXLEN){
        result[1] *= (comet[j] - 'A' + 1);
        j++;
    }

    printf("\nComet's No.: %ld\nGroup's No.: %ld",result[0],result[1]);
    printf("\nComet's No. Mod 47: %ld\nGroup's No. Mod 47: %ld",result[0]%47,result[1]%47);

    if(result[0]%47 == result[1]%47)
        printf("\nGO");
    else
        printf("\nSTAY");

    exit(0);
}

现在,据我所知,scanf()读取一个字符串,直到检测到空格。但在这里,输出是 -

Comet's Name: COMETQHVNGAT
Group's Name: HVNGAT
Comet's No.: 1
Group's No.: 1
Comet's No.: -534663680
Group's No.: 994500
Comet's No. Mod 47: 43
Group's No. Mod 47: 27
STAY

但是,不应该这样吗?

comet = "COMETQ" & Group = "HVNGAT"

我不明白为什么不发生这种情况?

此外,当comet的大小为6个字节时,如何存储 - COMETQHVNGAT

3 个答案:

答案 0 :(得分:2)

如果要将char数组用作字符串,则需要将其终止。

在您的代码中,数组长度指定为6,而您的输入本身为6字节,没有空间存储终止空字符。这就是为什么当cometgroup传递给printf()时,它们会产生奇怪的输出。

字符串以空值终止,并且基于此原则,您的案例中的内存访问将超出分配的内存大小cometgroup,从而生成undefined behaviour 。< / p>

更安全的选择:

使用fgets()读取输入,受缓冲区大小限制,摆脱最后\n个字符,然后你就可以了。查看man page了解详情。

此外,您需要将%ld的格式说明符%lu更改为unsigned long int%ld用于signed long int

答案 1 :(得分:1)

由于缓冲区大小#define MAXLEN 6 - 它导致Undefined Behavior - 终止字符\0没有空间。

COMETQ\0
0123457

MAXLEN定义为7。

答案 2 :(得分:1)

声明数组将以连续方式分配内存。所以在第一个字符串中你 无法给出空字符。所以这就是它完全打印的原因。

如果输入的输入小于maxlen,则输出正确。确保maxlen值很高,因为用户可以使用n个字符来命名。

检查:

如果打印两个数组的起始字符的地址,则可以得到6个字节的差异。