打印字符串有困难

时间:2015-06-16 18:49:50

标签: c arrays string printf scanf

当我运行该程序时,第二个printf()打印string2,扫描到附加到末尾的string1

e.g。已将123扫描到string1,然后打印:Is before "12ab123"。 而不是12ab

为什么不只是"12ab"

char string1[MAX_STR_LEN];
char string2[4]={'1','2','a','b'};
char five='5';
char abc[3]={'a','b','c'};
printf("Enter a string:");
scanf("%s", string1);
printf("Is before \"%s\":",string2);

5 个答案:

答案 0 :(得分:3)

字符串是C中的空终止字符数组。

更改

function generatePlayerId(){
    var tempId;
    do{
        tempId = Math.floor(Math.random()*7)+1;
    } while (id.indexOf(tempId) !== -1);
    return tempId;
}

char string2[4]={'1','2','a','b'};

(与char string2[5]={'1','2','a','b', '\0'}; 相同)

答案 1 :(得分:1)

您需要使用NULL character作为

终止数组

char string2[5]={'1','2','a','b','\0'};

当您执行scanf()时,string1存储在下一个内存中,因此正在使用string2打印string1。它会打印到\0所以Undefined Behavior

答案 2 :(得分:1)

在您的代码中

 char string2[4]={'1','2','a','b'};

string2不会以空值终止。使用 array 作为%s格式说明符的参数会调用未定义的行为,因为它在搜索空终止符时会超过分配的内存。

您需要自己添加null-terminator,如

char string2[5]={'1','2','a','b','\0'};

string2用作字符串

另外,您也可以写

char string2[ ]= "12ab";

允许编译器决定大小,它考虑(并添加)空终止符的空间。

同样适用于abc

那就是说,你扫描进入string1并打印string2,这当然没有错,但也没有多大意义。

答案 3 :(得分:1)

扩展前面的答案,由于变量在堆栈存储器中存储的顺序,字符串似乎已合并。在每种处理器体系结构或编译器上,这种效果并不总是相同的(优化器设置也可以更改此行为)。

答案 4 :(得分:0)

如果格式说明符%s没有精度标志,则函数输出字符,直到遇到零字符'\0'

字符数组string2的定义方式是它没有终止零

char string2[4]={'1','2','a','b'};

因此该函数输出数组之外的字符,直到它符合零字符。

您可以使用精确标志来明确指定要输出的字符数。例如

printf("Is before \"%4.4s\":",string2);    

或者您可以定义包含终止零的数组。例如

char string2[5] = { '1', '2', 'a', 'b', '\0' };

考虑到在这种情况下,如果指定数组的大小应该至少等于5(尽管大小可以大于5;在这种情况下,没有初始化器的其他字符将为零 - 初始化)

或只是

char string2[] = { "12ab" };

或没有大括号

char string2[] = "12ab";