第一章学习笔记
序
- 1,c缺乏“安全网”特性,不对数组下标引用和指针访问做有效性检查。这样提升了效率,但也增加了风险。但可以自己进行检查;
一、简介
/*
** 这个程序从标准输入中读取输入行并在标准输出中打印这些输入行,
** 每个输入行的后面一行是该行内容的一部分。
**
** 输入第一行是一串列标号,串的最后以一个负数结尾。
** 这些列标号成对出现,说明需要打印的输入行的列的范围。
** 例如,0 3 10 12 -1 表示从第0列到第3列,第10列到第12列的内容将被打印。
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLS 20 /*能处理的最大行*/
#define MAX_INPUT 1000 /*每个输入行的最大长度*/
int read_column_numbers(int columns[],int max);
void rearrange(char *output,char const *input,int
n_columns,int const columns[]);
int main(void){
int n_columns; /*需要进行处理的列标号*/
int columns[MAX_COLS]; /*需要进行处理的列数*/
char input[MAX_INPUT]; /*容纳输入行的数组*/
char output[MAX_INPUT]; /*容纳输出行的数组*/
/*
** 读取该串列标号
*/
n_columns = read_column_numbers(columns,MAX_COLS);
/*
*创建一个文件流指针
*/
FILE *fp;
fp = fopen("test.txt","r");//打开一个test文件
while(fgets(input,MAX_INPUT,fp)!=NULL){
printf("ORIGINAL INPUT:%s\n",input);
rearrange(output,input,n_columns,columns);
printf("Rearranged line:%s\n",output);
}
return EXIT_SUCCESS;
}
int read_column_numbers(int columns[],int max)
{
int num=0;
int ch;//这里ch用来接收字符,但是定义为整型,这是因为要和EOF比较,而EOF是整型;
while(num<max && scanf("%d",&columns[num]) == 1 && columns[num]>=0)
num += 1;
if(num % 2 != 0){
puts("LAST columns number is not paired.");
exit(EXIT_FAILURE);
}
while((ch=getchar())!= EOF && ch != '\n')
;
return num;
}
void rearrange(char *output,char const *input,int n_columns,int const columns[])
{
int col;
int output_col;
int len;
len =strlen(input);
output_col=0;
for(col = 0; col < n_columns; col += 2){
int nchars = columns[col+1] - columns[col]+1;
if(columns[col] >= len || output_col==MAX_INPUT-1)
break;
if(output_col + nchars > MAX_INPUT-1)
nchars = MAX_INPUT - output_col -1;
strncpy(output + output_col,input + columns[col], nchars);
output_col += nchars;
}
output[output_col]='\0';
}
-
1.注释与预处理通过/*注释掉的代码段,不会被编译。而通过#if…#endif是可选择性的注释,可操作性非常强;
-
2.标量和常量按值传递,在函数返回时做的然后修改都会失效,而数组为引用,做的改变会产生效果;
-
3.NUL表示“\0”,而NULL表示指针指向一块空内存。他们都是整型值,所以可以互换,但是为了更好理解0的意思,所以各有其作用。NUL没有预定义,想使用必须自己定义。#define NUL “\0”;
-
4.未给变量赋初值,它的初始值将是一个不可预料的值,就是垃圾!当然第一次操作是赋值另论;
-
5.%c会读取空格,%s不能读带有空格的字符串;
-
6.字符为小整型,EOF为整型,EOF不能用char类型接受,必须使用更长的整型。EOF在<stdio.h>中;
-
7.strncpy可以在最后一个参数指定复制位数,strcpy用第二个字符串直接覆盖第一个字符串,strcat将第二个字符串接到第一个字符串,strchr在第一个字符串搜素第二个字符第一次出现的位置,strstr在第一个字符串,找第二个字符串第一次出现的位置;
-
8."%g"自动选择使用%e(科学计数法)或者%f表示;
fgets 函数
char *fgets(char *str,int n,FILE *stream);
FLIE *fp;
char str[n];
fp = fopen("test.txt","r");
if(fp==NULL)return -1;
if(fgets(str,n,fp)!=NULL){
put(str);
}
- str是接受输入的数组;
- n为读取字符串的最大个数,通常为数组大小;
- stream是指向FILE对象的指针;
- fopen有点迷;
- fgets函数读取到n-1或者读到换行符就会停止;
编程练习
- 1.2 编写一个程序,从标准输入读取几行输入。每行输入都要打印在标准输出上,前面要加上行号。在编写这个程序时要试图让程序能够处理的输入行的长度没有限制。
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch;
int line;
int at_beginning;
line = 0;
at_beginning = 1;
while((ch=getchar())!=EOF){
if(at_beginning==1){
at_beginning=0;
line += 1;
printf("%d",line);
}
putchar(ch);
if(ch=='\n'){
at_beginning=1;
}
}
return EXIT_SUCCESS;
}
-
1.5 rearranger当字符列范围超出输入行的末尾就停止复制,这只在序列递增的情况下才是正确的,试修改,使其不按顺序读取也是正确的。
void rearrange(char *output,char const *input,int n_columns,int const columns[]) { int col; int output_col; int len; len =strlen(input); output_col=0; for(col = 0; col < n_columns; col += 2){ int nchars = columns[col+1] - columns[col]+1; /* **如果输入行没那么长,跳出这个范围; */ if(columns[col]>=len) continue; /* **如果输出数组已满,任务完成; */ if(output_col == MAX_INPUT - 1) break; /*if(columns[col] >= len || output_col==MAX_INPUT-1) break;//仅输入递增有序才正确*/ /* *如果输出数组空不够,只复制可容纳部分; * */ if(output_col + nchars > MAX_INPUT-1) nchars = MAX_INPUT - output_col -1; /* **观察有多少字符在这个范围内,如果他们小于nchars, **对nchars进行调整 **/ if(columns[col] + nchars-1>=len) nchars = len - columns[col]; strncpy(output + output_col,input + columns[col], nchars); output_col += nchars; } output[output_col]='\0'; }

浙公网安备 33010602011771号