C语⾔中字符的输⼊输出以及计算字符个数的⽅法详解
C语⾔字符输⼊与输出
标准库提供的输⼊/输出模型⾮常简单。⽆论⽂本从何处输⼊,输出到何处,其输⼊/输出都是按照字符流的⽅式处理。⽂本流是由多⾏字符构成的字符序列,⽽每⾏字符则由 0 个或多个字符组成,⾏末是⼀个换⾏符。标准库负责使每个输⼊/输出流都能够遵守这⼀模型。使⽤标准库的 C 语⾔程序员不必关⼼在程序之外这些⾏是如何表⽰的。
标准库提供了⼀次读/写⼀个字符的函数,其中最简单的是 getchar 和 putchar 两个函数。每次调⽤时,getchar 函数从⽂本流中读⼊下⼀个输⼊字符,并将其作为结果值返回。也就是说,在执⾏语句
c = getchar()
之后,变量 c 中将包含输⼊流中的下⼀个字符。这种字符通常是通过键盘输⼊的。
每次调⽤ putchar 函数时将打印⼀个字符。例如,语句
putchar()
将把整型变量 c 的内容以字符的形式打印出来,通常是显⽰在屏幕上。putchar 与 printf 这两个函数可以交替调⽤,输出的次序与调⽤的次序⼀致。
借助于 getchar 与 putchar 函数,可以在不了解其它输⼊/输出知识的情况下编写出数量惊⼈的有⽤的代码。最简单的例⼦就是把输⼊⼀次⼀个字符地复制到输出,其基本思想如下:
读⼀个字符
while(该字符不是⽂件结束指⽰符)
输出刚读⼊的字符
读下⼀个字符
将上述基本思想转换为 C 语⾔程序为:
#include <stdio.h>
/* copy input to output; 1st version*/
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
其中,关系运算符!=表⽰“不等于”。
字符在键盘、屏幕或其它的任何地⽅⽆论以什么形式表现,它在机器内部都是以位模式存储的。char 类型专门⽤于存储这种字符型数据,当然任何整型(int)也可以⽤于存储字符型数据。因为某些潜在的重要原因,我们在此使⽤ int 类型。
这⾥需要解决如何区分⽂件中有效数据与输⼊结束符的问题。C 语⾔采取的解决⽅法是:在没有输⼊时,getchar 函数将返回⼀个特殊值,这个特殊值与任何实际字符都不同。这个值称为 EOF(end of file,⽂件结束)。我们在声明变量 c 的时候,必须让它⼤到⾜以存放 getchar 函数返回的任何值。这⾥之所以不把 c 声明成 char 类型,是因为它必须⾜够⼤,除了能存储任何可能的字符外还要能存储⽂件结束符 EOF。因此,我们将 c 声明成 int 类型。
EOF 定义在头⽂件<stdio.h>中,是个整型数,其具体数值是什么并不重要,只要它与任何 char 类型的值都不相同即可。这⾥使⽤符号常量,可以确保程序不需要依赖于其对应的任何特定的数值。
对于经验⽐较丰富的 C 语⾔程序员,可以把这个字符复制程序编写得更精炼⼀些。在 C 语⾔中,类似于
c = getchar()
之类的赋值操作是⼀个表达式,并且具有⼀个值,即赋值后左边变量保存的值。也就是说,赋值可以作为更⼤的表达式的⼀部分出现。如果将为 c 赋值的操作放在 while 循环语句的测试部分中,上述字符复制程序便可以改写成下列形式:
#include <stdio.h>
/
* copy input to output; 2nd version
*/
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
在该程序中,while 循环语句⾸先读⼀个字符并将其赋值给 c,然后测试该字符是否为⽂件结束标志。如果该字符不是⽂件结束标志,则执⾏ while 语句体,并打印该字符。随后重复执⾏ while 语句。当到达输⼊的结尾位置时,while 循环语句终⽌执⾏,从⽽整个 main 函数执⾏结束。
以上这段程序将输⼊集中化,getchar 函数在程序中只出现了⼀次,这样就缩短了程序,整个程序看起
来更紧凑。习惯这种风格后,读者就会发现按照这种⽅式编写的程序更易阅读。我们经常会看到这种风格。(不过,如果我们过多地使⽤这种类型的复杂语句,编写的程序可能会很难理解,应尽量避免这种情况。)
对 while 语句的条件部分来说,赋值表达式两边的圆括号不能省略。不等于运算符!=的优先级⽐赋值运算符=的优先级要⾼,这样,在不使⽤圆括号的情况下关系测试!=将在赋值=操作之前执⾏。因此语句
c = getchar() != EOF
等价于语句
c = (getchar() != EOF)
该语句执⾏后,c 的值将被置为 0 或 1(取决于调⽤ getchar 函数时是否碰到⽂件结束标志),这并不是我们所希望的结果。
计算字符个数
下列程序⽤于对字符进⾏计数:
#include <stdio.h>
/* 统计输⼊的字符数 Version 1.0 */
main()
{
long nc;
nc = 0;
while(getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
其中,语句 ++nc; 引⼊了⼀个新的运算符++,其功能是执⾏加 1 操作。可以⽤语句 nc = nc + 1 代替它,但语句++nc 更精炼⼀些,且通常效率也更⾼。与该运算符相应的是⾃减运算符--。++与--这两个运算符既可以作为前缀运算符(如++nc),也可以作为后缀运算符(如 nc++)。我们在后⾯将看到,这
两种形式在表达式中具有不同的值,但++nc 与 nc++都使 nc 的值增加1。⽬前,我们只使⽤前缀形式。
该字符计数程序使⽤ long 类型的变量存放计数值,⽽没有使⽤ int 类型的变量。long整型数(长整型)⾄少要占⽤ 32 位存储单元。在某些机器上 int 与 long 类型的长度相同,但在⼀些机器上,int 类型的值可能只有 16 位存储单元的长度(最⼤值为32767),这样,相当⼩的输⼊都可能使 int 类型的计数变量溢出。转换说明%ld 告诉 printf 函数其对应的参数是 long 整型。使⽤ double(双精度浮点数)类型可以处理更⼤的数字。我们在这⾥不使⽤ while 循环语句,⽽⽤ for 循环语句来展⽰编写此循环的另⼀种⽅法:
#include <stdio.h>
/* count characters in input; 2nd version */
main()
{
double nc;
for (nc = 0; getchar() != EOF; ++nc)
;
printf("%.0f\n", nc);
}
对于 float 与 double 类型。printf 函数都使⽤%f 进⾏说明。%.0f 强制不打印⼩数点和⼩数部分,因此⼩数部分的位数为 0。
在该程序段中,for 循环语句的循环体是空的,这是因为所有⼯作都在测试(条件)部分与增加步长部分完成了。但 C 语⾔的语法规则要求 for 循环语句必须有⼀个循环体,因此⽤单独的分号代替。单独的分号称为空语句,它正好能满⾜ for 语句的这⼀要求。把它单独放在⼀⾏是为了更加醒⽬。
在结束讨论字符计数程序之前,我们考虑以下情况:如果输⼊中不包含字符,那么,在第⼀次调⽤ getchar 函数的叫
候,while 语句或 for 语句中的条件测试从⼀开始就为假,程序的执⾏结果将为 0,这也是正确的结果。这⼀点很重要。whi1e 语句与 for 语句的优点之⼀就是在执⾏循环体之前就对条件进⾏测试,如果条件不满⾜,则不执⾏循环体,这就可能出现循环体⼀次都不执⾏的情况。在出现 0 长度的输⼊时,程序的处理应该灵活⼀些,在出现边界条件时,while 语句与 for 语句有助
于确保程序执⾏合理的操作。
连接两个字符串的程序:
#include <stdio.h>
#include <string.h>
void main()
{
int i;
char str1[30]="welcome to ";
char str2[]= "wamagic";
printf("%s\n",strcat(str1,str2));
scanf("%d", &i);
}
在MFC下实现计算字符串的程序:
void CNowaMagic_MFCDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
//CDialogEx::OnOK();
//获得EDIT
cstring转为intCEdit* pBoxOne;
pBoxOne = (CEdit*) GetDlgItem(IDC_EDIT1);
CString str;
CString sStrLen;
char tmp[10] = "";
pBoxOne-> GetWindowText(str);
int nStrLen = str.GetLength();
sStrLen = itoa(nStrLen,tmp,10);
CString str2 = _T("字符数为:");
MessageBox(str2 + sStrLen,_T("程序运⾏结果"),MB_OK);
str.ReleaseBuffer();
}
程序运⾏结果如下:
为了更好地进⾏程序实践,推荐使⽤在MFC上也把程序实践⼀遍,有UI出来乐趣会更⼤。
⼀些细节如下:
定义 char tmp[10] = ""; 时如果不指定数组长度会造成内存越界。
⽤ str.GetLength(); ⽅法获取 CString 的长度。
itoa(int,str,10) 可以将整数转换成字符串。int 就是要转的整数,str是存放转后的字符串,10是模式(还有其他模式)。连接两个 CString 可以直接⽤ + 操作符。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论