我在文件中有一个矩阵,我想计算行数和列数。矩阵元素用空格分隔:
1 2.3 4 5 ..etc
3 4 6.77 9
8 .....
........
etc
我找到了一个计算列数的函数..它的工作方式就像魅力一样:
int getColumn(FILE* fp)
{
char buff[BUFSIZ]={0};
int count=0;
char *p;
if(NULL==fgets(buff, BUFSIZ, fp))
return -1;
rewind(fp);
for(p=buff;NULL!=strtok(p, " \t\n");p=NULL)
++count;
return count;
}
现在我想制作一个类似的函数getRow()来计算行..但我真的不明白getColumn()如何工作我有一些替代getRow()但我读到它是不是很安全的玩EOF ..(在事实上我遇到了问题)例如:
int getRow(FILE* fp)
{
int ch=0;
int count=1;
while(!feof(fp))
{
ch = fgetc(fp);
if(ch == '\n')
count++;
}
return count;
}
计算C中文本文件中的行
我将尝试解释它是如何工作的。首先,你必须了解函数getColumn是什么。
简短回答:它读取输入文件的第一行(如果有)并返回由以下之一分隔的项目数:space,tab或newline。
答案很长:首先检查是否有东西要读:
if(NULL == fgets(buff, BUFSIZ, fp))
return -1;
函数fgets从文件中获取一行,这意味着它在换行符上停止(或者如果指定的大小小于行的实际大小)。在上面的例子中,fgets尝试从fp指向的文件中读取BUFFSIZ - 1个字符,并将它们存储在字符数组buff中(-1因为保留了换行符)。但是,如果没有要读取的字符,fgets将返回NULL并退出该函数。
另一方面,如果返回值不为NULL,则该行存储在数组buff中。这里的假设是该线符合BUFSIZ。
BTW BUFSIZ是GNU C库中定义的宏,如下所示:
Macro:int BUFSIZ此宏的值是一个整数常量表达式,可用于setvbuf的size参数。该值保证至少为256(link)。
然后在循环中检查数组buff:
for(p=buff; NULL!=strtok(p, " \t\n"); p=NULL)
++count;
for循环通过函数strtok在数组buff上循环。 strtok“用于隔离以null结尾的字符串中的顺序令牌”,strtok将检查buff直到终止字符'\ 0',但是,只要遇到其中一个指定的分隔符,“\ t \ n”,它就会返回指向项目的指针,输入循环并递增计数。在第一次调用时,必须使用指针调用strtok,但是每次对strtok的后续调用都必须使用NULL,这就是为什么在for循环的第三个表达式中将p设置为NULL的原因。
如何读取行并计算它们
#define BUFFSIZE 1024
int countlines (FILE *fin)
{
int nlines = 0;
char line[BUFFSIZE];
while(fgets(line, BUFFSIZE, fin) != NULL) {
nlines++;
}
return nlines;
}
我们再次读取BUFFSIZE - 1个字符,但我更喜欢手动设置BUFFSIZE。
最后的评论
计算行和列的正确方法是仅使用一个函数。在读取每一行时,您可以计算列数。如果您确定输入文件是正确的(并且所有行具有相同的列数),则可以仅在第一行上对列进行计数,或者可以为每行计算它们。
试试:
while(ch != EOF)
{
// Code goes in here
}
而不是feof()
。