我遇到的问题如下:我想从键盘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;
}
答案 0 :(得分:0)
strncpy()
不会终止字符串,您需要处理它,否则您的代码将导致未定义的行为。
另外
M=4
并且您正在复制5个字符,这将导致未定义的行为。
答案 1 :(得分:0)
这是因为你的字符串没有被终止。您需要在每个缓冲区中为字符串末尾的'\ 0'字符留出额外空间。将所有缓冲区增大1,将ether设置为0以
开头memset(&buf1, 0, sizeof(buf1));
或将该缓冲区的最后一个索引显式设置为'\ 0'
答案 2 :(得分:0)
#define M 4
...
char s1[M],s2[M],s3[M+1];
...
strncpy(s1,buffer,5)
在上面的代码中(从程序中提取),您将5
个字节(或更少)复制到大小为4
的缓冲区中。当buffer
包含大小为4
(strlen(buffer) == 4
)的字符串时,strncpy(s1, buffer, 5)
将5
个字符复制到s1
,第五个字符为{NUL
1}}字符(字符串终止符)。
由于s1
只有4
个字符的空间,因此终结符写入的内存不属于s1
但属于不同的变量。
当您处理用户输入以避免缓冲区溢出时,建议使用strncpy()
而不是strcpy()
。但是,你在这里完成的只是一个缓冲区溢出。
解决方案很简单,它涉及两个简单的步骤:
s1
和s2
声明为char [5]
; 在任何地方使用M
,避免代码中的硬编码常量;使用常量(#define
s)可以根据需要更容易地更改值:
...
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`)
答案 3 :(得分:-1)
在您的代码中,
strncpy(s1,buffer,5);
创建内存溢出,因为s1
仅分配了4
个字节。这反过来调用undefined behaviour。
相同
strncpy(s2,buffer,5);
解决方案:
使用#define M 5
或保留#define M 4
,并定义您的数组,如
char s1[M+1],s2[M+1],s3[M+1];
这样,就有足够的空间来存储终止空值。 (\0
)