【问题标题】:(C) Char array size changes after input ?(C) 输入后字符数组大小发生变化?
【发布时间】:2015-04-07 12:15:19
【问题描述】:

以下有什么区别? (三)

char x[100] ;
char y[] = ""; // no space between the double quotations
char z[] = " "; // space between the double quotations

如果用户在数组 y 中输入了一个输入,例如“test”,它的大小会变为 5 吗?

char y[] ="";
gets(y); // user entered "test"

如果用户在数组 x 中输入大于 100 的输入,它的大小会改变吗?

char x[100] ;
gets(x); // user entered an input larger than 100

以及为什么这段代码有效:(如果用户输入“test”,它将打印“test”)

#include<stdio.h>
#include<string.h>
int main(){
    char name[] = " " ; // space between the double quotations 
    gets(name);
    for(int i=0 ; i< strlen(name) ; i++) {
        printf("%c",name[i]);
    }
    return 0 ;
}

而这个没有? (这会打印奇怪的符号)(如果用户输入“test”,它将打印“t”和笑脸符号)

#include<stdio.h>
#include<string.h>
int main(){
    char name[] = "" ; // no space between the double quotations 
    gets(name);
    for(int i=0 ; i< strlen(name) ; i++) {
        printf("%c",name[i]);
    }
    return 0 ;
}

这个让我抓狂,它没有循环,即使双引号之间没有空格

#include<stdio.h>
#include<string.h>
int main(){
    char name[] = "" ; // no space between the double quotations
    gets(name);
    printf("%c",name[0]);
    printf("%c",name[1]);
    printf("%c",name[2]);
    printf("%c",name[3]);
    return 0 ;
}

即使双引号之间没有空格,这个也可以使用 ( puts ) :

#include<stdio.h>
#include<string.h>

int main(){
    char name[] = "" ;
    gets(name);
    puts(name);
    return 0 ;
}

【问题讨论】:

  • 这是你的作业吗?
  • 永远不要使用gets(),特别是在你的情况下,这是一个非常糟糕的主意。
  • @SouravGhosh '\0' 呢?
  • @SouravGhosh 是您的编译器显示的错误吗? ...我正在使用 DevCpp,它没有显示错误

标签: c arrays string char


【解决方案1】:

不,数组没有调整大小。

它之所以起作用,是因为行为是未定义的,并且可能发生的事情之一就是它起作用了。

当你这样做时,你写入超出了数组的范围,根据非法写入位置的数据,会发生不同的事情。

永远不要使用gets(),因为它不能防止程序正在执行的缓冲区溢出,您应该使用fgets() 函数,该函数将数组的大小作为参数,以防止写入超过该大小的字节数组

fgets(array, sizeOfTheArray, stdin);

可以防止问题发生,并且代码不会像您认为的那样“工作”。

另外,c 中的字符串不会在任何地方存储它的大小,所以像你一样调用strlen() 是不好的,这个

for(int i=0 ; i< strlen(name) ; i++)
               /*  ^ do not do this */

导致性能不佳,可以像这样存储值

size_t length = strlen(name);
for(int i = 0 ; i < length ; i++)

或者,使用 c 字符串是非nul 字节后跟nul 字节的序列,像这样

for(int i = 0 ; name[i] != '\0' ; i++)

【讨论】:

  • 非常感谢您的帮助:),未定义的行为信息非常有用......我喜欢这个循环的想法 for(int i = 0 ; name[i] != '\0 ' ; i++)
【解决方案2】:

如果用户在数组 y 中输入了一个输入,例如“test”,它的大小会变为 5 吗?

没有。数组的大小是恒定的。(y 的情况下为 1)

如果用户在数组 x 中输入大于 100 的输入,它的大小会改变吗?

没有。数组的大小是恒定的。(x 的情况下为 100)

在这两种情况下,代码都会触发Undefined Behavior(这意味着任何事情都可能发生),因为输入的额外字符被写入无效位置。这也是the gets() function is dangerous 的原因!原因是gets() 不会阻止buffer overflows

以及为什么此代码有效:(如果用户输入“test”,它将打印“test”)

如果输入的长度超过一个字符,任何事情都可能发生。再次,因为Undefined Behavior

它可以在没有循环的情况下工作,即使双引号之间没有空格

UB

即使双引号之间没有空格,这个也可以使用 ( puts ) :

UB

【讨论】:

    猜你喜欢
    • 2013-10-07
    • 2017-02-10
    • 1970-01-01
    • 2022-07-06
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    相关资源
    最近更新 更多