为什么此代码无法在数组中打印字符?

时间:2018-09-10 07:50:33

标签: c

我使用gcc(tdm-1)5.1.0编译了此代码,请告诉我为什么输出中不包含“ hello”

#include<stdio.h>
void main()
{
    int i;
    char st[20];
    printf("Enter a string ");
    scanf("%s",st);
    for(i=0;i<20;i++)
{
    printf("%c",st[i]);
}

}
  

输入:你好   输出:@ @

3 个答案:

答案 0 :(得分:4)

您将打印数组的所有20个元素,但是如果用户输入的字符串小于该字符串,则不会初始化所有元素。它们将不确定并且看似随机。

请记住,C语言中的char字符串实际上称为 空终止 字节字符串以null结尾的位很重要,这意味着您可以通过再次检查当前字符'\0'(即终止符)来轻松找到字符串的结尾。

或者您可以只使用strlen函数来获取字符串的长度:

for(i=0;i<strlen(st);i++) { ... }

或使用"%s"格式打印字符串:

printf("%s", st);

还要注意,在没有任何保护的情况下,scanf函数将允许您输入比数组中的空间更长的输入,因此您需要再次保护字符,例如通过限制字符数{{1} }将显示为:

scanf

现在为什么不显示输入内容,这是因为未初始化元素的不确定内容。虽然您不会超出数组的范围,但仍然超出了实际字符串的范围。越界导致undefined behavior

可能发生的 是一些“随机”不确定的内容恰好是回车符scanf("%19s",st); // Write at most 19 character (*plus* terminator) to the string ,它将光标移动到行的开始并且输出已经写入的内容将被数组中未初始化的元素覆盖。

答案 1 :(得分:1)

下面是一个简短的示例,正​​如Qubit所解释的:

Sub connectToCISDB()

Dim dbCon As New ADODB.Connection
Dim recordSet As New ADODB.recordSet
Dim strQuery, strCon As String

strQuery = "select * from SAPSR3.eanlh;"

Set dbCon = New ADODB.Connection      
dbCon.Open "Provider=OraOLEDB.Oracle;User ID=xautotext;Password=F7_kxxxxZS;Data Source=ouxxpdxx1"

答案 2 :(得分:0)

这里

char st[20];

st是局部变量,默认数组st的内容是垃圾,不为零。因此,如果您扫描少于20个字符到st中,则在这种情况下,数组st的剩余位置包含垃圾,因此它会打印一些{{ 1}}(对于

@ @

&这是一个不好的习惯,因为用户输入了几个字符(例如5个字符),然后循环旋转了char st[20]; printf("Enter a string "); scanf("%s",st); for(i=0;i<20;i++) { printf("%c",st[i]); } 次,在内部它将执行更多的操作或消耗更多的CPU周期。

因此,如果要按char打印一个 char数组char ,则应旋转循环,直到遇到20 char,例如

\0

如其他人建议的那样,您可以使用for(i=0;st[i];i++) { /* this fails when \0 encounters */ printf("%c",st[i]); } 格式说明符,例如使用单个st来打印字符数组printf

%s

另外,最好在声明自身的同时初始化char数组st。例如

printf("%s\n",st); /*here printf starts printing from base address of st 
                    and prints until \0 */