缓冲区和数组的输入输出问题

    最近编写程序的时候一直被数据的输入输出所困扰,由此写篇博文总结一下最近遇到的问题和解决方法,错误之处望指正。

    1.数组使用的一些语法注意事项

     (1)数组的定义

               一维数组:类型名  数组名 [常量表达式]

               常量表达式中可以包括常量和符号常量,如int a[3+5]合法,int [a]不合法,即C语言不允许对数组的大小进行动态定义。

               如果在被调用函数中(不包括主函数)定义数组,其长度可以是变量或者是非常量表达式,如:

void fun(int n)
{
   int a[2*n]
   .......
   ......
}
               在调用fun函数时,形参n从实参得到值,这种情况被称为“可变长数组”,允许在每次调用fun函数时,n有不同的值。但是在执行的时候,n的值是不可变的,数组长度是固定的。如果指定数组为静态(static),存储方式,则不能使用“可变长数组”,如static int a[2*n],不合法。

               二维数组:类型名  数组名 [常量表达式][常量表达式]

                int arr[3][4],可以把arr[0],arr[1],arr[2],看成是数组名,即二维数组可以理解为数组的数组

      (2)数组的初始化

                定义数组的时候赋初值,并指定数组的长度:int arr[5] = {1,2,3,4,5}

                定义数组的时候赋初值,不指定数组的长度,此时系统会根据初值的个数确定数组的长度,int arr[] = {1,2,3,4,5},数组的长度为5

               定义数组的时候赋部分值:int arr[5] = {1,2},只给前二个赋值,系统会自动给后面三个赋初值为0,此时如果将数组里面的数据打印出来的话,打印的结果是12000。

               定义数组时,如果已经定义了数组的长度并对之初始化,凡未被初始化的部分,系统会自动初始化,整型数组初始化为0,字符型数组初始化为'\0',指针数组为NULL。

              二维数组初始化的几种形式,int arr[2][3] = {{1,2,3},{4,5,6}},int arr[2][3] = {1,2,3,4,5,6},int arr[2][3] = {{1},{2}}(未被初始化的部分自定义为0),int arr[2][3] = {{1}}

             注意:如果全部元素都被赋初值,则定义数组时对第一维数组的长度可以不指定,但是第二维数组的长度不能省

   2.字符数组使用中的语法注意

     (1)字符数组的结束标志

                C语言规定字符数组的结束标志为'\0',这个字符不算数组的有效长度中去,'\0',在ASCII码为0。

                例如输出一个字符串,printf("I am happy\n");,在内存中存储时,系统会自动的在'\n'的后面加上一个'\0',在执行printf函数时,每输出一个字符检查一次,看下一个字符是否为'\0',遇到'\0'的时候停止输出。

      (2)字符数组初始化

       char ch[10] = {'I',' ','a','m',' ','h','a','p','p','y'};
              如果字符的个数大于字符数组的长度,则语法错误,如果初始化字符的个数,小于数组的长度,系统会自动补'\0'

       char ch[] = {'I',' ','a','m',' ','h','a','p','p','y'};
              如果定义时长度不确定,系统会根据初始化的字符个数确定数组长度,此时数组的长度为10,如果我们以字符串的形式同样的输入上面的字符,则数组的长度不是10,而是11,因为系统会自动的在后面加上'\0'。下面截图可以看出单个字符和字符串初始化数组的区别

 缓冲区和数组的输入输出问题_第1张图片

但是此时如果用printf("%s",arr1),将数组打印出来时,'\0'是不会被打印出来的

3.缓冲区和数组的输入输出问题

   (1)逐个字符的输入和输出用"%c",字符串的输入和输出用"%s",如scanf("%s",arr);此时输入字符串时,输入的字符串的长度应该小于已经定义的字符数组的长度,因为系统会自动的不'\0',如果是单个字符输入时,输入的数据的长度可以是定义的字符数组的长度。如果利用一个scanf()输入多个字符串,输入时应该以空格隔开如

      char str1[5],str2[5],str3[5];
      scanf("%s%s%s",str1,str2,str3);
          如果此时输入"how are you",系统会分别把“how”,“are”,"you",赋值给str1,str2,str3

         注意:如果编写以下程序,则不会达到想要的结果

     char str[13];
     scanf("%s",str);
           此时如果输入"how are you",由于系统把空格当做是输入字符串之间的空格符,因此只讲空格前面的"how"赋值给了str,其余的部分补'\0'。还应该注意的是,scanf的输入项中如果是字符数组名,不要在前面加&,因为C语言中,数组名代表的就是数组的首地址,如果我们使用printf("%o",str),此时是用八进制输出数组str的首地址。

          在使用VS2013时,系统为了更加安全会让你使用scanf_s,此时的用法和scanf略有不同,不只需要传数组名还需要传入输入字符串的长度如下

      char arr[10];
      scanf_s("%s",arr,10);
         注意: 此时仍需要保证输入的字符串的长度小于定义的字符数组的长度,如果输入字符的个数超过数组的长度,就会把数组撑爆了,此时的scanf_s的返回值为0,如果用printf打印的话,则打印不了。,输入字符的个数最大还应该比数组长度小1,因为系统会自动补'\0'。使用gets_s函数时的用法相类似,gets(arr,10)。

       注意:gets_s()使用时,就不存在用空格作为字符串的分隔符,如下

     char arr[10];
     gets_s(arr,10);
         如果此时输入“hello ha”此时arr中存储的就是“hello ha\0\0”

    (2)一些常见的字符串处理函数(字符串处理函数时,应包含头文件

            puts(str):字符串输出函数

            gets(str):字符串输入函数,返回值是str的起始地址(put和gets只能输入输出一个字符串)

            strlen(str):测量字符串长度函数,测试结果是字符串的实际长度,不包括'\0'

            strcmp(str1,str2):字符串比较函数,比较规则是,将两个字符串自左到右逐个比较(按ASCII码值大小比较),直到出现不同的字符或者遇到'\0'为止,如果相等返回0,如果str1>str2返回一个正整数,否则返回一个负整数
      (3)字符输入和输入缓冲区的问题

             先说两个单个字符的输入和输出函数getchar(),putchar(),具体用法不在熬述。先看下面的程序



未完待续,对不起

            





你可能感兴趣的:(C语言)