expected declaration or statement at end of input 哭!!各位大虾,这错怎么查啊!
:325:1: 错误:expected declaration or statement at end of input
325:1: 错误:expected declaration or statement at end of input
325,326就是程序的最后两行。找了个线程并发拷贝程序,这个错误总是弄不明白,网上查了很多,但是我觉得函数有事先定义好,括号也匹配,还是不行,求大家帮帮忙!
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<pthread.h>
#define PSIZE 4096 /*管道文件的大小*/
#define BSIZE 128 /*默认缓冲区的大小*/
#define NOFILE 20 /*u_ofile表可分配的个数*/
#define NFILE 20 /*p_file表可分配的个数*/
#define NPIPE 20 /*p_fcb可分配的个数*/
/*进程的u_file表*/
int u_ofile[NOFILE];
/*模拟file表*/
struct
{
char f_flag;/*读写标志,'w'表示写,'r'表示读*/
int f_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/
int f_inode;/*对应的p_fcb表下标*/
long f_offset;/*读写指针,当前已读或已写个数*/
}p_file[NFILE];
/*管道控制块*/
struct
{
char *p_addr;/*管道文件基地址*/
int p_size;/*管道文件大小,PSIZE*/
int p_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/
}p_fcb[NPIPE];
/*模拟管道文件*/
char *pfile;
/*管道的写入写出端*/
int fd[2];
/*锁机制,实现互斥*/
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/*进程间通信,实现同步*/
pthread_cond_t rflag = PTHREAD_COND_INITIALIZER;/*读信号量*/
pthread_cond_t wflag = PTHREAD_COND_INITIALIZER;/*写信号量*/
/*线程创建函数只能传一个参数,用结构体来封装所有参数*/
struct arg_set
{
char *fname; /*文件名*/
int f; /*传递fdp[]*/
};
/*u_ofile表初始化*/
int u_ofile_init()
{
int i;
for(i=0;i<NOFILE;i++)
u_ofile[i] = -1;
u_ofile[0]=0;
u_ofile[1]=0;
u_ofile[2]=0;
return 0;
}
/*创建管道*/
int ppipe(int a[])
{
int i;
for(i=0;i<NOFILE;i++)
{
if(u_ofile[i]==-1)
{
a[0] = i;/*读*/
u_ofile[i] = 0;/*读端*/
break;
}
}
for(i;i<NOFILE;i++)
{
if(u_ofile[i]==-1)
{
a[1] = i;/*写*/
u_ofile[i] = 1;/*写端*/
break;
}
}
if(i>=NOFILE)
{
printf("u_ofile分配失败\n");
return -2;
}
pfile = (char *)malloc(PSIZE*sizeof(char));/*申请模拟管道用的内存空间*/
if(pfile==NULL)/*申请可能不成功*/
{
return -1;
}
for(i=0;i<NFILE;i++)
{
if(p_file[i].f_count!=1)
{
p_file[i].f_flag = 'r';/*读标志*/
//p_file[i].f_inode = 0;/*读对应p_fcb表下标*/
p_file[i].f_count = 1;/*p_file[0]这个表项在被使用,不可再分配*/
p_file[i].f_offset = 0;/*读指针*/
u_ofile[a[0]] = i;/*读端*/
break;
}
}
for(i=0;i<NFILE;i++)
{
if(p_file[i].f_count!=1)
{
p_file[i].f_flag = 'w';/*写标志*/
//p_file[i].f_inode = 0;/*写对应p_fcb控制块下标*/
p_file[i].f_count = 1;/*p_file[1]这个表项在被使用,不可再分配*/
p_file[i].f_offset = 0;/*写指针*/
u_ofile[a[1]] = i; /*写端*/
break;
}
}
if(i>=NFILE)
{
return -1;
}
for(i=0;i<NPIPE;i++)
{
if(p_fcb[i].p_count==0)
{
p_fcb[i].p_addr = pfile;/*给管道文件基地址赋值*/
p_fcb[i].p_size = PSIZE;/*管道文件大小*/
p_fcb[i].p_count = 2;/*读写都在进行,此p_fcb表项不可再分*/
p_file[u_ofile[a[0]]].f_inode = i;
p_file[u_ofile[a[1]]].f_inode = i;
break;
}
}
if(i>=NPIPE)
{
return -1;
}
return 0;/*分配成功*/
}
/*关闭管道*/
int p_close(int a[])
{
char *p;
int i;
for(i=0;i<2;i++)
{
p=p_fcb[p_file[u_ofile[a[i]]].f_inode].p_addr;
if(p!=NULL)
free(p); /*释放管道内存*/
p_fcb[p_file[u_ofile[a[i]]].f_inode].p_count = 0; /*管道控制块计数清零*/
p_file[u_ofile[a[i]]].f_count = 0; /*file表项计数清零*/
u_ofile[a[i]] = -1; /*u_ofile表项清空*/
a[i] = -1; /*fdp[]清空*/
}
return 0;
}
/*写管道*/
int writep(int fd,char *ca,int n)
{
long offr,offw;/*读写指针,实际是读写字符个数*/
int r;/*管道文件读端*/
int m;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/
int w = u_ofile[fd];/*管道文件写端*/
int pf = p_file[w].f_inode;/*读管道对应的p_fcb表的下标*/
int n1 = n;/*一次应该写入的字符个数*/
int wstart = 0;/*计数器,写入字符个数*/
int i = 0
for(i;i<NFILE;i++)/*寻找写管道对应的读管道的读端*/
{
if((p_file[i].f_flag=='r')&&(p_file[i].f_inode==pf))
{
r = i;
break;
}
else
{
continue;
}
}
pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/
offr = p_file[r].f_offset;/*赋值读指针*/
offw = p_file[w].f_offset;/*赋值写指针*/
if((offw+n1-PSIZE)>offr)/*不能一次写完*/
{
if(p_fcb[pf].p_count==0)/*对文件的复制操作已进行结束,管道文件被释放*/
{
return 0;
}
else
{
m = PSIZE+offr-offw;/*最多可写入数*/
for(wstart=0;wstart<m;wstart++)
{
*(p_fcb[pf].p_addr+offw%PSIZE) = *ca;
ca++;
offw++;
}
p_file[w].f_offset = offw;/*重定位写指针位置*/
n1 = n1-m;/*剩余需要读的字符个数*/
pthread_cond_signal(&rflag);/*唤醒读线程,管道可读*/
pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/
}
}
/*一次性可将ca中内容全部写入管道*/
offr = p_file[r].f_offset;
offw = p_file[w].f_offset;
for(wstart=0;wstart<n1;wstart++)
{
/*printf("%d\n",p_fcb[pf].p_addr);*/
*(p_fcb[pf].p_addr+offw%PSIZE) = *ca;
/*printf("%d\n",wstart);*/
ca++;
offw++;
}
p_file[w].f_offset = offw;
pthread_cond_signal(&rflag);
pthread_mutex_unlock(&lock);
return n;/*返回写入字符个数*/
}
/*读管道*/
int readp(int fd,char *ca,int n)
{
long offr,offw;/*读写指针,实际是读写字符个数*/
int w;/*管道文件写端*/
int m;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/
int r = u_ofile[fd];/*管道文件读端*/
int pf = p_file[r].f_inode;/*读管道对应的p_fcb表的下标*/
int rstart = 0;/*计数器,读出字符个数*/
int i = 0;
for(i;i<NFILE;i++)/*寻找读管道对应的读管道的端*/
{
if((p_file[i].f_flag=='w')&&(p_file[i].f_inode==pf))
{
w = i;
break;
}
else
{
continue;
}
}
pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/
offr = p_file[r].f_offset;/*赋值读指针*/
offw = p_file[w].f_offset;/*赋值写指针*/
if(offr==offw)/*管道空,无内容可读*/
{
if(p_fcb[pf].p_count==1)/*写端关闭*/
{
p_fcb[pf].p_count--;/*文件的复制以完成,释放管道文件的空间*/
return 0;
}
else
{
pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/
pthread_cond_wait(&rflag,&lock);/*写线程封锁等待*/
}
}
offr = p_file[r].f_offset;
offw = p_file[w].f_offset;
m = n<=(offw-offr)?n:(offw-offr);/*得到可读字符个数*/
for(rstart=0;rstart<m;rstart++)
{
*ca = *(p_fcb[pf].p_addr+offr%PSIZE);
ca++;
offr++;
}
p_file[r].f_offset = offr;/*重定位读指针位置*/
pthread_cond_signal(&wflag);
pthread_mutex_unlock(&lock);
return m;
}
/*线程调用,读源文件,写管道*/
void *pwrite(void *a)
{
char abuf1[BSIZE];
struct arg_set *args=(struct arg_set *)a;/*需要传入多个参数时,用结构体传*/
int fdr;
int n_r;/*管道文件写入字符数*/
if((fdr=open(args->fname,O_RDONLY))!=-1)
{
while((n_r=read(fdr,abuf1,BSIZE))>0)/*读文件,写管道*/
writep(args->f,abuf1,n_r);
p_fcb[p_file[u_ofile[args->f]].f_inode].p_count--;/*文件已读完,关闭管道写端*/
}
else
{
perror(args->fname);/*打开源文件可能不成功*/
}
return NULL;
}
/*线程调用,写目标文件,读管道*/
void *pread(void *a)
{
char abuf2[BSIZE];/*缓冲区*/
struct arg_set *args=(struct arg_set *)a;/*需要传入多个参数时,用结构体传*/
int fdw;
int n_w;/*管道文件读出字符数*/
if((fdw=open(args->fname,O_CREAT|O_RDWR,0777))!=-1)
{
while((n_w=readp(args->f,abuf2,BSIZE))>0)/*读管道,写文件*/
write(fdw,abuf2,n_w);
}
else
{
perror(args->fname);/*打开目标文件可能出错*/
}
return NULL;
}
/*主函数*/
int main(int argc,char *argv[])
{
int x;
u_ofile_init();
while((x=ppipe(fd))==-1);/*创建管道,即申请空间*/
if(x==-2)
return -1;
pthread_t t;
struct arg_set args[2];/*用结构体传写线程需要的参数:文件名,管道文件读写端*/
args[0].fname=argv[1];/*源文件名*/
args[0].f=fd[1];/*管道文件写端*/
args[1].fname=argv[2];/*目标文件名*/
args[1].f=fd[0];/*管道文件读端*/
pthread_create(&t,NULL,pwrite,(void *)&args[0]);/*创建子线程,写管道*/
pread((void *)&args[1]);/*主线程调用,读管道*/
pthread_join(t,NULL);/*等待写线程结束*/
p_close(fd);
return 0;
}
有分号什么的落下已经改正了,就差这个错误!
[解决办法]
文件末尾空行问题。
如果没有空行,就加一个空行。
如果有空行,就把那空行删了。
记不太清了。
[解决办法]
一个地方粗心,少了分号
另外pwrite 与 pread是unistd中的库函数,你非常巧的撞车了,你应该换个名字
#include<stdio.h>#include <stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<pthread.h>#define PSIZE 4096 /*管道文件的大小*/#define BSIZE 128 /*默认缓冲区的大小*/#define NOFILE 20 /*u_ofile表可分配的个数*/#define NFILE 20 /*p_file表可分配的个数*/#define NPIPE 20 /*p_fcb可分配的个数*//*进程的u_file表*/int u_ofile[NOFILE];/*模拟file表*/struct { char f_flag;/*读写标志,'w'表示写,'r'表示读*/ int f_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/ int f_inode;/*对应的p_fcb表下标*/ long f_offset;/*读写指针,当前已读或已写个数*/}p_file[NFILE];/*管道控制块*/struct{ char *p_addr;/*管道文件基地址*/ int p_size;/*管道文件大小,PSIZE*/ int p_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/}p_fcb[NPIPE];/*模拟管道文件*/char *pfile;/*管道的写入写出端*/int fd[2];/*锁机制,实现互斥*/pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;/*进程间通信,实现同步*/pthread_cond_t rflag = PTHREAD_COND_INITIALIZER;/*读信号量*/pthread_cond_t wflag = PTHREAD_COND_INITIALIZER;/*写信号量*//*线程创建函数只能传一个参数,用结构体来封装所有参数*/struct arg_set{ char *fname; /*文件名*/ int f; /*传递fdp[]*/};/*u_ofile表初始化*/int u_ofile_init(){ int i; for(i=0;i<NOFILE;i++) u_ofile[i] = -1; u_ofile[0]=0; u_ofile[1]=0; u_ofile[2]=0; return 0;}/*创建管道*/int ppipe(int a[]){ int i; for(i=0;i<NOFILE;i++) { if(u_ofile[i]==-1) { a[0] = i;/*读*/ u_ofile[i] = 0;/*读端*/ break; } } for(i;i<NOFILE;i++) { if(u_ofile[i]==-1) { a[1] = i;/*写*/ u_ofile[i] = 1;/*写端*/ break; } } if(i>=NOFILE) { printf("u_ofile分配失败\n"); return -2; } pfile = (char *)malloc(PSIZE*sizeof(char));/*申请模拟管道用的内存空间*/ if(pfile==NULL)/*申请可能不成功*/ { return -1; } for(i=0;i<NFILE;i++) { if(p_file[i].f_count!=1) { p_file[i].f_flag = 'r';/*读标志*/ //p_file[i].f_inode = 0;/*读对应p_fcb表下标*/ p_file[i].f_count = 1;/*p_file[0]这个表项在被使用,不可再分配*/ p_file[i].f_offset = 0;/*读指针*/ u_ofile[a[0]] = i;/*读端*/ break; } } for(i=0;i<NFILE;i++) { if(p_file[i].f_count!=1) { p_file[i].f_flag = 'w';/*写标志*/ //p_file[i].f_inode = 0;/*写对应p_fcb控制块下标*/ p_file[i].f_count = 1;/*p_file[1]这个表项在被使用,不可再分配*/ p_file[i].f_offset = 0;/*写指针*/ u_ofile[a[1]] = i; /*写端*/ break; } } if(i>=NFILE) { return -1; } for(i=0;i<NPIPE;i++) { if(p_fcb[i].p_count==0) { p_fcb[i].p_addr = pfile;/*给管道文件基地址赋值*/ p_fcb[i].p_size = PSIZE;/*管道文件大小*/ p_fcb[i].p_count = 2;/*读写都在进行,此p_fcb表项不可再分*/ p_file[u_ofile[a[0]]].f_inode = i; p_file[u_ofile[a[1]]].f_inode = i; break; } } if(i>=NPIPE) { return -1; } return 0;/*分配成功*/}/*关闭管道*/int p_close(int a[]){ char *p; int i; for(i=0;i<2;i++) { p=p_fcb[p_file[u_ofile[a[i]]].f_inode].p_addr; if(p!=NULL) free(p); /*释放管道内存*/ p_fcb[p_file[u_ofile[a[i]]].f_inode].p_count = 0; /*管道控制块计数清零*/ p_file[u_ofile[a[i]]].f_count = 0; /*file表项计数清零*/ u_ofile[a[i]] = -1; /*u_ofile表项清空*/ a[i] = -1; /*fdp[]清空*/ } return 0;}/*写管道*/int writep(int fd,char *ca,int n){ long offr,offw;/*读写指针,实际是读写字符个数*/ int r;/*管道文件读端*/ int m;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/ int w = u_ofile[fd];/*管道文件写端*/ int pf = p_file[w].f_inode;/*读管道对应的p_fcb表的下标*/ int n1 = n;/*一次应该写入的字符个数*/ int wstart = 0;/*计数器,写入字符个数*/ int i = 0 ;//---------->分号 for(;i<NFILE;i++)/*寻找写管道对应的读管道的读端*/ { if((p_file[i].f_flag=='r')&&(p_file[i].f_inode==pf)) { r = i; break; } else { continue; } } pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/ offr = p_file[r].f_offset;/*赋值读指针*/ offw = p_file[w].f_offset;/*赋值写指针*/ if((offw+n1-PSIZE)>offr)/*不能一次写完*/ { if(p_fcb[pf].p_count==0)/*对文件的复制操作已进行结束,管道文件被释放*/ { return 0; } else { m = PSIZE+offr-offw;/*最多可写入数*/ for(wstart=0;wstart<m;wstart++) { *(p_fcb[pf].p_addr+offw%PSIZE) = *ca; ca++; offw++; } p_file[w].f_offset = offw;/*重定位写指针位置*/ n1 = n1-m;/*剩余需要读的字符个数*/ pthread_cond_signal(&rflag);/*唤醒读线程,管道可读*/ pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/ } } /*一次性可将ca中内容全部写入管道*/ offr = p_file[r].f_offset; offw = p_file[w].f_offset; for(wstart=0;wstart<n1;wstart++) { /*printf("%d\n",p_fcb[pf].p_addr);*/ *(p_fcb[pf].p_addr+offw%PSIZE) = *ca; /*printf("%d\n",wstart);*/ ca++; offw++; } p_file[w].f_offset = offw; pthread_cond_signal(&rflag); pthread_mutex_unlock(&lock); return n;/*返回写入字符个数*/}/*读管道*/int readp(int fd,char *ca,int n){ long offr,offw;/*读写指针,实际是读写字符个数*/ int w;/*管道文件写端*/ int m;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/ int r = u_ofile[fd];/*管道文件读端*/ int pf = p_file[r].f_inode;/*读管道对应的p_fcb表的下标*/ int rstart = 0;/*计数器,读出字符个数*/ int i = 0; for(i;i<NFILE;i++)/*寻找读管道对应的读管道的端*/ { if((p_file[i].f_flag=='w')&&(p_file[i].f_inode==pf)) { w = i; break; } else { continue; } } pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/ offr = p_file[r].f_offset;/*赋值读指针*/ offw = p_file[w].f_offset;/*赋值写指针*/ if(offr==offw)/*管道空,无内容可读*/ { if(p_fcb[pf].p_count==1)/*写端关闭*/ { p_fcb[pf].p_count--;/*文件的复制以完成,释放管道文件的空间*/ return 0; } else { pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/ pthread_cond_wait(&rflag,&lock);/*写线程封锁等待*/ } } offr = p_file[r].f_offset; offw = p_file[w].f_offset; m = n<=(offw-offr)?n:(offw-offr);/*得到可读字符个数*/ for(rstart=0;rstart<m;rstart++) { *ca = *(p_fcb[pf].p_addr+offr%PSIZE); ca++; offr++; } p_file[r].f_offset = offr;/*重定位读指针位置*/ pthread_cond_signal(&wflag); pthread_mutex_unlock(&lock); return m;}/*线程调用,读源文件,写管道*/void *pwrite1(void *a)//pwrite unistd.h的库函数{ char abuf1[BSIZE]; struct arg_set *args=(struct arg_set *)a;/*需要传入多个参数时,用结构体传*/ int fdr; int n_r;/*管道文件写入字符数*/ if((fdr=open(args->fname,O_RDONLY))!=-1) { while((n_r=read(fdr,abuf1,BSIZE))>0)/*读文件,写管道*/ writep(args->f,abuf1,n_r); p_fcb[p_file[u_ofile[args->f]].f_inode].p_count--;/*文件已读完,关闭管道写端*/ } else { perror(args->fname);/*打开源文件可能不成功*/ } return NULL;}/*线程调用,写目标文件,读管道*/void *pread1(void *a)//pread unistd.h的库函数{ char abuf2[BSIZE];/*缓冲区*/ struct arg_set *args=(struct arg_set *)a;/*需要传入多个参数时,用结构体传*/ int fdw; int n_w;/*管道文件读出字符数*/ if((fdw=open(args->fname,O_CREAT|O_RDWR,0777))!=-1) { while((n_w=readp(args->f,abuf2,BSIZE))>0)/*读管道,写文件*/ write(fdw,abuf2,n_w); } else { perror(args->fname);/*打开目标文件可能出错*/ } return NULL;}/*主函数*/int main(int argc,char *argv[]){ int x; u_ofile_init(); while((x=ppipe(fd))==-1);/*创建管道,即申请空间*/ if(x==-2) return -1; pthread_t t; struct arg_set args[2];/*用结构体传写线程需要的参数:文件名,管道文件读写端*/ args[0].fname=argv[1];/*源文件名*/ args[0].f=fd[1];/*管道文件写端*/ args[1].fname=argv[2];/*目标文件名*/ args[1].f=fd[0];/*管道文件读端*/ pthread_create(&t,NULL,pwrite1,(void *)&args[0]);/*创建子线程,写管道*/ pread1((void *)&args[1]);/*主线程调用,读管道*/ pthread_join(t,NULL);/*等待写线程结束*/ p_close(fd); return 0;}