第六章函数-Read
- 格式:doc
- 大小:132.00 KB
- 文档页数:35
linux中使用c语言read的用法在Linux中,使用C语言的read函数可以从文件描述符中读取数据。
read函数的原型如下:```c#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);```参数说明:- `fd`:文件描述符,可以是打开文件的文件描述符、标准输入文件描述符(0)、标准输出文件描述符(1)、标准错误文件描述符(2)等。
- `buf`:存放读取数据的缓冲区地址。
- `count`:读取的最大字节数。
返回值:- 如果成功,返回实际读取的字节数。
- 如果到达文件末尾,返回0。
- 如果发生错误,返回-1,并设置errno。
示例如下:```c#include <stdio.h>#include <unistd.h>#include <fcntl.h>int main() {int fd;ssize_t n;char buf[100];// 打开文件fd = open("file.txt", O_RDONLY);if (fd == -1) {perror("open");return -1;}// 读取文件内容n = read(fd, buf, sizeof(buf));if (n == -1) {perror("read");return -1;}// 输出读取的内容printf("Read %zd bytes: %.*s\n", n, (int)n, buf);// 关闭文件close(fd);return 0;}```以上示例中,首先通过open函数打开一个文件,然后使用read函数从文件中读取数据到缓冲区buf中,最后通过printf 函数输出读取的内容。
读写偏移量是文件指针在读写文件时的一个重要概念,而read函数作为文件读取操作中的一个关键函数,其每次读完数据后会改变读写偏移量,本文将就read函数每次读完读写偏移量这一问题展开讨论。
1. read函数的作用read函数是C语言中的文件操作函数之一,其作用是从文件中读取数据。
read函数的原型为:```csize_t read(int fd, void *buf, size_t count);```其中fd为文件描述符,buf为存放读入数据的缓冲区,count为要读取的字节数。
read函数会从文件中读取count个字节的数据,然后将数据存放到buf中。
2. 读写偏移量的概念在进行文件读写操作时,系统会为每个打开的文件维护一个读写偏移量。
该偏移量表示下一次操作将从文件的哪个位置开始进行,即在读取数据时从文件的哪个位置开始读取,或者在写入数据时从文件的哪个位置开始写入。
每次读写操作完成后,系统会自动更新读写偏移量,使其指向下一个要操作的位置。
3. read函数每次读完数据后的读写偏移量在调用read函数读取数据时,系统会根据读写偏移量确定从文件的哪个位置开始读取数据。
读取完成后,系统会自动更新读写偏移量,使其指向文件中的下一个位置。
read函数每次读完数据后,读写偏移量会发生变化。
4. 对读写偏移量的操作系统提供了一系列函数用于对读写偏移量进行操作,主要包括lseek、ftell和fseek等函数。
其中lseek函数用于移动文件读写位置,ftell 函数用于获取当前读写位置,fseek函数用于移动文件读写位置并进行读写操作。
5. 解决read函数每次读完数据后的问题为了解决read函数每次读完数据后的读写偏移量问题,可以使用lseek函数显式地控制读写偏移量。
在调用read函数读取数据之前,可以使用lseek函数将读写偏移量设置到想要读取的位置,这样就可以确保每次读取数据时都从指定位置开始读取,而不会受到上一次读写操作的影响。
read和write函数 每⼀个TCP套接⼝有⼀个发送缓冲区,可以⽤SO_SNDBUF套接⼝选项来改变这个缓冲区的⼤⼩。
当应⽤进程调⽤ write时,内核从应⽤进程的缓冲区中拷贝所有数据到套接⼝的发送缓冲区。
如果套接⼝的发送缓冲区容不下应⽤程序的所有数据(或是应⽤进程的缓冲区⼤于套接⼝发送缓冲区,或是套接⼝发送缓冲区还有其他数据),应⽤进程将被挂起(睡眠)。
这⾥假设套接⼝是阻塞的,这是通常的缺省设置。
内核将不从write 系统调⽤返回,直到应⽤进程缓冲区中的所有数据都拷贝到套接⼝发送缓冲区。
因此从写⼀个TCP套接⼝的write调⽤成功返回仅仅表⽰我们可以重新使⽤应⽤进程的缓冲区。
它并不告诉我们对端的 TCP或应⽤进程已经接收了数据。
TCP取套接⼝发送缓冲区的数据并把它发送给对端TCP,其过程基于TCP数据传输的所有规则。
对端TCP必须确认收到的数据,只有收到对端的ACK,本端TCP才能删除套接⼝发送缓冲区中已经确认的数据。
TCP必须保留数据拷贝直到对端确认为⽌。
任何UDP套接字也有缓冲区⼤⼩,不过它仅仅是可写到该套接字的UDP数据报的⼤⼩上线,如果⼀个应⽤进程写⼀个⼤于套接字发送缓冲区⼤⼩的数据报,内核将返回⼀个EMSGSIZE错误,既然UDP是不可靠的,他不必保存应⽤进程数据的副本因此不需⼀个真正的缓冲区。
(应⽤进程的数据在沿协议栈向下传递时,通常被复制到某种格式的⼀个内核缓冲区中,然⽽当数据被发送后,这个副本被数据链路层丢弃了)函数定义:ssize_t write (int fd, const void * buf, size_t count); 函数说明:write()会把参数buf所指的内存写⼊count个字节到参数放到所指的⽂件内。
write成功返回,只是buf中的数据被复制到了kernel中的TCP发送缓冲区。
⾄于数据什么时候被发往⽹络,什么时候被对⽅主机接收,什么时候被对⽅进程读取,系统调⽤层⾯不会给予任何保证和通知。
readwrite函数调⽤read函数从打开⽂件读数据。
#include<unistd.h>ssize_t read( int filedes, void *buf, size_t nbytes);从 filedes 中读取数据到 buf 中,nbytes 是要求读到的字节数。
返回值:若成功则返回实际读到的字节数,若已到⽂件尾则返回0,若出错则返回-1。
当从终端设备读时,通常⼀次最多读⼀⾏。
ssize_t 提供带符号的返回值,size_t不带符号。
调⽤write函数向打开的⽂件写数据。
#include<unistd.h>ssize_t write (int filedes, const void *buf, size_t nbytes);从 buf 中写数据到 filedes 中,nbytes 是相求写⼊的字节数。
返回值:返回值通常与参数 nbytes相同,否则表⽰出错。
⽂件描述符 filedes是⼀个 int型数,通常⽤⽂件描述符0与进程的标准输⼊相关联,⽂件描述符1与进程的标准输出相关联,⽂件描述符2与进程的标准出错输出相关联。
在依从POSIX的应⽤程序中,幻数0,1,2应当替换成符号常量 STDIN_FILENO,STDOUT_FILENO 和STDERR_FILENO。
这些常量都定义在头⽂件<unistd.h>中。
标准输⼊/输出常量 stdin 和 stdout定义在头⽂件 <stdio.h>中,分别表⽰标准输⼊和标准输出⽂件。
是指针类型,struct _IO_FILE *进程终⽌时,系统会关闭该进程的所有打开的⽂件描述符,所以程序不⽤关闭输⼊和输出⽂件。
当度量⼀个进程的执⾏时间时,unix系统使⽤三个进程时间值:1. 时钟时间2. ⽤户cpu时间3. 系统cpu时间时钟时间是进程运⾏的时间总量。
⽤户cpu时间是执⾏⽤户指令所⽤的时间。
系统cpu时间是为该进程执⾏内核程序所经历的时间。
C语⾔基础-read()函数读取⽂本字节导致判断失误的问题 ⼯作了⼏个⽉,闲着没事⼜拿起了经典的C程序设计看了起来,看到字符计数⼀节时想到⽤read()去读⽂本作为字符输⼊,⼀切OK,直到⾏计数时问题出现了,字符总计数没有问题,可⾏计算就是进⾏不了,思考了半天⼜找“⼤神”帮忙终于找到问题所在了,问题就出在条件判断的char与int的⽐较上: 问题的关键就在于read()的读取为直接写内存块,当读取⼀个字节时仅仅把读取到的⼀个字节写到内存的⼀个字节的地址上去,当⽤int 类型读取出来时,结果int的前三个字节还是处于垃圾数据的状态,将其与' '⼀个字节⽐较,必然出现不相等的情况,解决的办法为在开始即将int c初始化为0,或者将int 强制转化为char 类型,避免前三个垃圾数据加⼊⽐较中。
总结就是,⼀个好习惯真的很重要,⼀定要记得初始化。
1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/types.h>4 #include <fcntl.h>56int main(int argc, char **argv)7 {8int fd;9long nc = 0;10long lc = 0;11long tc = 0;1213int c;14int ret;1516 printf("c = %c, %08x, %d, %c\n", c, c, c, (char)(c));17 fd = open(argv[1], O_RDONLY);1819while ((ret = read(fd, &c, 1)) != 0) {20 printf("c = %c, 0x_c = %08x d = %d c_char = %c\n", c, c, c, (char)(c));21 nc++;22if (c == '') {23 lc++;24 } else if (c == '\t') {25 tc++;26 }27 }2829 printf("char count: %ld\n", nc);30 printf("line count: %ld\n", lc);31 printf("table count: %ld\n", tc);3233 close(fd);3435return0;36 }。
read方法Read 方法是一种在编程中非常常见的方法,它用于从文件或其他数据源中读取信息。
在本文中,我们将深入探讨 Read 方法的用法、常见的应用场景以及一些注意事项。
首先,我们来看一下 Read 方法的基本用法。
在大多数编程语言中,Read 方法通常用于从文件中读取数据。
它可以按照指定的格式读取数据,并将其存储在变量中供后续处理和分析。
例如,在Python 中,我们可以使用 open() 函数打开一个文件,然后使用read() 方法从文件中读取数据。
在其他编程语言中,也有类似的方法来实现文件读取操作。
除了从文件中读取数据,Read 方法还可以用于从其他数据源中读取信息,比如从网络请求中读取数据,或者从数据库中读取数据。
无论是从文件、网络还是数据库中读取数据,Read 方法都可以帮助我们轻松地获取所需的信息。
在实际应用中,Read 方法有许多常见的应用场景。
例如,在Web 开发中,我们经常需要从服务器端读取数据并将其显示在网页上。
这时,我们就可以使用 Read 方法来完成这一操作。
另外,在数据分析和处理领域,Read 方法也经常被用于从文件或数据库中读取大量数据,并进行进一步的分析和处理。
然而,在使用 Read 方法时,我们也需要注意一些事项。
首先,我们需要确保所读取的数据源是存在的,并且有相应的读取权限。
其次,我们需要注意处理可能出现的异常情况,比如文件不存在或者网络连接超时等。
此外,我们还需要注意及时关闭文件或释放资源,以避免资源泄露或占用过多的系统资源。
总之,Read 方法是编程中非常常用的方法,它可以帮助我们轻松地从文件或其他数据源中读取信息。
在使用 Read 方法时,我们需要注意处理可能出现的异常情况,并及时释放资源,以确保程序的稳定性和效率。
希望本文对你有所帮助,谢谢阅读!。
readexcel函数
Readexcel函数是一种VBA函数,可以在Microsoft Excel中用于读取数据、把数据写入工作表或导出到CSV文件。
它通过在单元格中执行复
杂的计算公式实现从Excel中获取数据的目的。
它的工作原理是,当执行函数时,它会读取每一行Excel中包含的内容,并将获取的相应信息存放到矩阵中,最终返回一个矩阵,里面包含所
有读取出来的信息。
要使用Readexcel函数,首先在指定工作表或对应的工作簿中指定包含
数据的活页簿名称,然后调用Readexcel函数。
基本参数:
1. 工作簿名称:指定获取数据的工作簿名称。
2. 可选参数:指定从第一个工作表开始读,或从指定的工作表开始读
取数据。
Readexcel函数的其他可选参数,使可以指定要从工作簿中获取数据的
区域、列和行。
还可以定义其他基本参数,如是否排除空行、空列以
及字段信息等。
Readexcel函数可以有效读取Excel中大部分数据,比如表格、图形和
日期。
它具有可控性强、操作简单的特性,使用Readexcel函数可以实现从Excel中读取大量数据的目的,从而节省时间。
read函数参数理解当不传入size参数时,read()函数会一次性读取整个文件的内容,并返回一个字符串。
例如,假设有一个名为test.txt的文件,其中包含以下内容:```Hello, World!This is a test file.```可以使用如下代码读取整个文件的内容:```pythonfile = open('test.txt', 'r')content = file.readprint(content)file.close```输出结果为:```Hello, World!This is a test file.当传入一个size参数时,read()函数会按照指定的字符数读取文件。
读取的内容是一个字符串,包含最多size个字符。
例如,可以使用如下代码每次读取5个字符的内容:```pythonfile = open('test.txt', 'r')content = file.read(5)print(content)content = file.read(5)print(content)file.close```第一次读取5个字符的输出结果为:```Hello```第二次读取5个字符的输出结果为:```, Wor可以看到,read()函数每次读取size个字符,读取的位置会随着读取的次数逐渐向后移动。
当读取的内容不足size个字符时,read()函数会返回实际读取的字符数。
当读取到文件末尾时,再次调用read()函数将返回空字符串。
下面的例子演示了这种情况:```pythonfile = open('test.txt', 'r')content = file.read(20)print(content)content = file.read(20)print(content)file.close```第一次读取20个字符的输出结果为:```Hello, World!This i```第二次读取20个字符的输出结果为:```s a test file.```除了read()函数以外,还有其他类似的读取文件内容的方法,如readline()函数和readlines()函数。
第六章函数一、选择题1. 有以下程序#include<stdio.h>float f1(float n){return n*n;}float f2(float n){return 2*n;}void main(){float (*p1)(float),(*p2)(float),(*t)(float), y1, y2;p1=f1; p2=f2;y1=p2( p1(2.0) );t = p1; p1=p2; p2 = t;y2=p2( p1(2.0) );printf("%3.0f, %3.0f\n",y1,y2);}程序运行后的输出结果是______。
A)8, 16 B)8, 8 C)16, 16 D)4, 8 答案:A2. 有以下函数int fun(char *a,char *b){while((*a!='\0')&&(*b!='\0')&&(*a==*b)){a++;b++;}return(*a-*b);}该函数的功能是______。
A)计算a和b所指字符串的长度之差B)将b所指字符串连接到a所指字符串中C)将b所指字符串连接到a所指字符串后面D)比较a和b所指字符串的大小答案:D3.有以下程序#include <string.h>#include <stdio.h>struct STU{char name[10];int num;};void f(char *name, int num){struct STU s[2]={{"SunDan",20044},{"Penghua",20045}};num = s[0].num;strcpy(name, s[0].name);}void main(){struct STU s[2]={{"YangSan",20041},{"LiSiGuo",20042}},*p;p=&s[1]; f(p->name, p->num);printf("%s %d\n", p->name, p->num);}程序运行后的输出结果是______。
A)SunDan 20042 B)SunDan 20044C)LiSiGuo 20042 D)YangSan 20041答案:A4.有以下程序#include <stdio.h>struct STU{char name[10]; int num; float TotalScore;};void f(struct STU *p){struct STU s[2]={{"SunDan",20044,550},{"Penghua",20045,537}}, *q=s;++p ; ++q; *p=*q;}void main(){struct STU s[3]={{"YangSan",20041,703},{"LiSiGuo",20042,580}};f(s);printf("%s %d %3.0f\n", s[1].name, s[1].num, s[1].TotalScore);}程序运行后的输出结果是______。
A)SunDan 20044 550 B)Penghua 20045 537C)LiSiGuo 20042 580 D)SunDan 20041 703答案:B5.有以下程序#include <stdio.h>struct STU{char name[10];int num;};void f1(struct STU c){struct STU b={"LiSiGuo",2042};c=b;}void f2(struct STU *c){struct STU b={"SunDan",2044};*c=b;}void main( ){struct STU a={"YangSan",2041},b={"WangYin",2043};f1(a);f2(&b);printf("%d %d\n",a.num,b.num);}执行后的输出结果是A)2041 2044 B)2041 2043 C)2042 2044 D)2042 2043答案:A13.以下程序的输出结果。
#include <stdio.h>void func(char **m);void main (){static char *a[ ]={"MORNING","AFTERTOON","EVENING"};char **n;n=a;func(n);}void func(char **m){++m;printf ("%s\n",*m);}A.为空B.MORNING C.AFTERTOON D.EVENING答案:C15. 有以下函数定义:void fun(int n,double x) {……}若以下选项中的变量都已经正确定义并赋值,则对函数fun的正确调用语句是。
A)fun(int y,double m); B)k=fun(10,12.5);C)fun(x,n); D)void fun(n,x);答案:C16. 以下程序运行后,输出结果是。
#include <stdio.h>int d=1;void fun (int p){int d=5;d+=p++;printf("%d",d);}void main( ){int a=3;fun(a);d+=a++;printf("%d\n",d);}A)84 B)99 C)95 D)44答案:A17. 以下程序的输出结果是。
#include <stdio.h>int x=3;void incre( ){static int x=1;x*=x+1;printf("%d ",x);}void main( ){int i;for (i=1;i<x;i++)incre( );}A)3 3 B)2 2 C)2 6 D)2 5答案:C18. 若程序中定义了以下函数:double myadd (double a,double b){return (a+b);}并将其放在调用语句之后,则在调用之前应该对该函数进行说明,以下选项中错误的说明是。
A)double myadd (double a,b);B)double myadd (double,double);C)double myadd (double b,double a);D)double myadd (double x,double y);答案:A21.以下叙述中正确的是。
A)全局变量的的作用域一定比局部变量的作用域范围大B)静态(static)类别变量的生存期贯穿于整个程序的运行期间C)函数的形参都属于全局变量D)未在定义语句中赋初值的auto变量和static变量的初值都是随机值答案:B22.以下函数fff(float x){ printf(“%d\n”,x*x);}的类型是A)与参数x的类型相同B)void类型C)int类型D)无法确定答案:C)23. 以下程序:#include <stdio.h>int func(int a,int b){int c;c=a+b;return c;}void main( ){int x=6,y=7,z=8, r;r=func((x--,y++,x+y), z--);printf("%d\n",r);}其输出结果是A)11 B)20 C)21 D)31答案:C)26. 有如下函数调用语句fuc(rec1,rec2+rec3,(rec4,rec5));该函数调用语句中,含有的实参个数是。
A)3 B)4 C)5 D)有语法错答案:A29.有以下程序#include <stdio.h>void fun(int *a,int i,int j){int t;if(i<j){t=a[i];a[i]=a[j];a[j]=t;i++; j--;fun(a,i,j);}}void main( ){int x[ ]={2,6,1,8},i;fun(x,0,3);for(i=0;i<4;i++) printf("%2d",x[i]);}程序运行后的输出结果是。
A)1 2 6 8 B)8 6 2 1 C)8 1 6 2 D)8 6 1 2 答案:C35. 若函数的形参为一维数组,则下列说法中正确的是()。
(A)调用函数时的对应实参必为数组名(B)形参数组可以不指定大小(C)形参数组的元素个数必须等于实参数组的元素个数(D)形参数组的元素个数必须多于实参数组的元素个数答案;(B)40. C语言程序由函数组成。
以下说法正确的是( )。
A)主函数必须在其它函数之前,函数内可以嵌套定义函数B)主函数可以在其它函数之后,函数内不可以嵌套定义函数C)主函数必须在其它函数之前,函数内不可以嵌套定义函数D)主函数必须在其它函数之后,函数内可以定义函数答案:B41.返回值为void的函数,其含义是( )。
A)调用函数之后,被调用的函数没有返回值B)调用函数之后,被调用的函数不返回C)调用函数之后,被调用的函数的返回值为任意的类型D)以上三种说法都是错误的答案:A42.若用数组名作为函数调用的实参,传递给形参的是( )。
A)数组的首地址B)数组第一个元素的值C)数组中全部元素的值D)数组元素的个数答案:A43.一个函数返回值的类型是由( )。
A)return语句中的表达式类型决定B)定义函数时所指定的函数类型决定C)调用该函数的主调函数的类型决定D)在调用函数时临时指定答案:B44.关于C语言以下说法正确的是( )。
A)只有当实参和与其对应的形参同名时才共占用存储单元B)形参是虚拟的,不占用存储单元C)实参和与其对应的形参各占用独立的存储单元D)实参和与其对应的形参共占用一个存储单元答案:. C47.有以下程序#include <stdio.h>int fun(int x){int p;if(x ==0 || x==1)return 3;elsep = x-fun(x-2);return p;}void main(){printf("\n%d",fun(9));}程序执行后的输出结果是_______。