在C中从键盘读取3个字符串但在打印时只获得两个字符串?

时间:2015-05-12 07:46:29

标签: 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];

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;
}

4 个答案:

答案 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包含大小为4strlen(buffer) == 4)的字符串时,strncpy(s1, buffer, 5)5个字符复制到s1,第五个字符为{NUL 1}}字符(字符串终止符)。

由于s1只有4个字符的空间,因此终结符写入的内存不属于s1但属于不同的变量。

当您处理用户输入以避免缓冲区溢出时,建议使用strncpy()而不是strcpy()。但是,你在这里完成的只是一个缓冲区溢出。

解决方案很简单,它涉及两个简单的步骤:

  • 也将s1s2声明为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