Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C从键盘上读3个字符串,但打印时只得到两个字符串?_C_Arrays_String_Char - Fatal编程技术网

用C从键盘上读3个字符串,但打印时只得到两个字符串?

用C从键盘上读3个字符串,但打印时只得到两个字符串?,c,arrays,string,char,C,Arrays,String,Char,我的问题是:我想从键盘上读取3个字符串s1、s2、s3。没有任何问题的最好方法是什么,然后我想打印这3个字符串。我给出了3个字符串,但在打印部分我只得到s2和s3,但s1是空的 这是我的密码员!: #include <stdio.h> #include <stdlib.h> #include <string.h> #define M 4 int main(){ char buffer[255]; char s1[M],s2[M],s3[M+1]; pri

我的问题是:我想从键盘上读取3个字符串s1、s2、s3。没有任何问题的最好方法是什么,然后我想打印这3个字符串。我给出了3个字符串,但在打印部分我只得到s2和s3,但s1是空的

这是我的密码员!:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4

int main(){

char buffer[255];
char s1[M],s2[M],s3[M+1];

printf("Give first string: ");
scanf("%s",buffer);

while(strlen(buffer) > 4){
    printf("lenght of string must be <= 4\n");
    printf("Give first String again : ");
    scanf("%s",buffer);
}
strncpy(s1,buffer,5);

printf("Give second string: ");
scanf("%s",buffer);


while(strlen(buffer) > 4){
    printf("lenght of string must be <= 4\n");
    printf("Give second String again : ");
    scanf("%s",buffer);
}

strncpy(s2,buffer,5);


printf("Give third string: ");
scanf("%s",buffer);


while(strlen(buffer) > 5){
    printf("lenght of string must be <= 5\n");
    printf("Give third String again : ");
    scanf("%s",buffer);
}
strncpy(s3,buffer,5);


printf("First String : %s\n",s1);
printf("Second String : %s\n",s2);
printf("Third String : %s\n",s3);

return 1;
}
在代码中

 strncpy(s1,buffer,5);
创建内存溢出,因为s1只分配了4个字节。这反过来又调用了

同样适用于

 strncpy(s2,buffer,5);
解决方案:

或者使用definem5

或者,继续定义M4,然后像这样定义数组

 char s1[M+1],s2[M+1],s3[M+1];
因此,有足够的空间来存储终止null\0

strncpy不为null,请终止字符串,您需要处理它,否则您的代码将导致未定义的行为


您正在复制5个字符,这将导致未定义的行为。

这是因为您的字符串没有终止。您需要在每个缓冲区中为字符串末尾的“\0”字符留出额外的空间。将所有缓冲区增大1,然后将以太设置为0

memset(&buf1, 0, sizeof(buf1)); 
或显式将该缓冲区的最后一个索引设置为“\0”

#define M 4
...
char s1[M],s2[M],s3[M+1];
...
strncpy(s1,buffer,5)
在上面从程序中提取的代码中,在大小为4的缓冲区中复制5个字节或更少的字节。当缓冲区包含大小为4的字符串strlenbuffer==4,strncpys1,buffer时,5将5个字符复制到s1,第五个字符是NUL字符,即字符串终止符

因为s1只能容纳4个字符,所以终止符写入的内存不属于s1,而是属于另一个变量

建议在处理用户输入时使用而不是,以避免缓冲区溢出。然而,您在这里完成的正是缓冲区溢出

解决方案很简单,包括两个简单的步骤:

将s1和s2也声明为char[5]; 在任何地方使用M,避免代码中硬编码的常量;如果需要,使用常量定义可以更轻松地更改值:

...

char s1[M+1],s2[M+1],s3[M+1];

printf("Give first string: ");
scanf("%s",buffer);

while(strlen(buffer) > M){
    printf("length of string must be <= %d\n", M);
    printf("Give first String again : ");
    scanf("%s",buffer);
}
strncpy(s1,buffer,M+1);

...
(repeat the changes above to `s2` and `s3`)

为什么要尝试将5个字符复制到最大值为4的数组中:strncpys1,buffer,5?请注意,标准C不了解键盘。你应该测试scanfCan返回的物品数量。请告诉我否决票背后的原因,以便我更正自己?谢谢-
...

char s1[M+1],s2[M+1],s3[M+1];

printf("Give first string: ");
scanf("%s",buffer);

while(strlen(buffer) > M){
    printf("length of string must be <= %d\n", M);
    printf("Give first String again : ");
    scanf("%s",buffer);
}
strncpy(s1,buffer,M+1);

...
(repeat the changes above to `s2` and `s3`)