【发布时间】:2011-01-09 09:05:03
【问题描述】:
如何计算每行中的字符数或数字数?是否有类似 EOF 的东西更像是行尾?
【问题讨论】:
标签: c
如何计算每行中的字符数或数字数?是否有类似 EOF 的东西更像是行尾?
【问题讨论】:
标签: c
您可以遍历行中的每个字符并不断增加计数器,直到遇到行尾 ('\n')。确保以文本模式 ("r") 而不是二进制模式 ("rb") 打开文件。否则流不会自动将不同平台的行尾序列转换为'\n' 字符。
这是一个例子:
int charcount( FILE *const fin )
{
int c, count;
count = 0;
for( ;; )
{
c = fgetc( fin );
if( c == EOF || c == '\n' )
break;
++count;
}
return count;
}
这是一个测试上述功能的示例程序:
#include <stdio.h>
int main( int argc, char **argv )
{
FILE *fin;
fin = fopen( "test.txt", "r" );
if( fin == NULL )
return 1;
printf( "Character count: %d.\n", charcount( fin ) );
fclose( fin );
return 0;
}
【讨论】:
关于逐行读取文件,看fgets。
char *fgets(char *restrict s, int n, FILE *restrict stream);
fgets() 函数应读取字节 从流到指向的数组 通过 s,直到读取 n-1 个字节,或者 被读取并传输到 s,或者文件结束条件是 遭遇。那么字符串是 以空字节结束。
这里唯一的问题可能是您不能保证文件中的最大行大小。如果是这种情况,您可以遍历字符直到看到换行符。
关于行尾:
简答:\n 是换行符(也称为换行符)。
长答案,来自维基百科:
基于 ASCII 或兼容的系统 字符集使用任一 LF(行 feed, 0x0A, 10 (十进制) 或 CR (回车,0x0D,十进制13) 单独,或 CR 后跟 LF (CR+LF, 0x0D 0x0A);见下文 CR+LF的历史原因 习俗。这些字符是基于 关于打印机命令:换行 表示一行纸 应该从打印机中送出,并且 回车表示 打印机托架应返回到 当前行的开头。
* LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
* CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
* CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
但由于您不太可能使用仅使用回车的表示形式,因此寻找换行符应该没问题。
【讨论】:
'\n',即使在 Windows 上也是如此。
如果您以文本模式打开文件,即fopen() 的第二个参数中没有b,您可以一个接一个地读取字符,直到您点击'\n' 来确定行大小。底层系统应该负责将行结束符转换为一个字符,'\n'。在某些系统上,文本文件的最后一行可能不以 '\n' 结尾,所以这是一种特殊情况。
伪代码:
count := 0
c := next()
while c != EOF and c != '\n'"
count := count + 1
上面将计算给定行中的字符数。 next() 是一个从文件中返回下一个字符的函数。
或者,您可以将fgets() 与缓冲区一起使用:
char buf[SIZE];
count = 0;
while (fgets(buf, sizeof buf, fp) != NULL) {
/* see if the string represented by buf has a '\n' in it,
if yes, add the index of that '\n' to count, and that's
the number of characters on that line, which you can
return to the caller. If not, add sizeof buf - 1 to count */
}
/* If count is non-zero here, the last line ended without a newline */
【讨论】:
SIZE 是一个方便的正整数值,可以是预处理器宏或幻数。我没有给你一个完整的代码,因为我不确定这是否是一个家庭作业问题。 :-)
SIZE 是128。然后,正如我在fgets() 之后的评论所说,如果buf 表示的字符串不包含换行符,则表示您的行更长超过 127 个字符。在这种情况下,您再次调用fgets(),并将count 增加127。因此,上面的代码将毫无问题地读取长行,并正确确定一行中的字符数。
最初的问题是如何获取“每一行”中的字符数(给定一行?还是当前行?),而答案大多给出了如何确定文件中第一行长度的解决方案.可以轻松地应用其中一些来确定当前行的长度(无需事先猜测缓冲区的最大长度)。
但是,在实践中通常需要的是文件中任何行的最大长度。然后可以保留一个缓冲区并使用 fgets 逐行读取文件并使用一些不错的函数(strtok、strtod 等)来解析行。在实践中,您可以使用任何先前的解决方案来确定一条线的长度,只需扫描所有线并取最大值。
一个逐字符读取文件的简单脚本:
max=0; i=0;
do
if ((c=fgetc(f))!= EOF && c!='\n') i++;
else {
if (i>max) max=i;
i=0;
}
while (c!=EOF);
return max;
注意:在实践中,为最大长度设置一个上限就足够了。一个肮脏的解决方案是使用文件大小作为最大行长度的上限。
【讨论】:
\n 是 C 中的换行符。在其他语言中,例如 C#,您可以使用类似 C# 的Environment.EndLine 来克服平台困难。
如果您已经知道您的字符串是一行(我们称之为 line),请使用strlen(line) 获取其中的字符数。如果以 '\n' 结尾,则减 1。
如果字符串中有换行符,您需要将其拆分为换行符,然后在每个子字符串上调用strlen()。
【讨论】:
你需要
返回
功能:
#include <stdio.h>
#include <string.h>
int getLengthOfLine(FILE* df,int Ofline){
char cchar;
int line=1;
int total =1;
int atLine=0;
int afterLine=0;
while ((cchar=fgetc(df))!=EOF)
{
if (feof(df)){
break ;
}
if (cchar == '\n' || cchar == '\0'){
if(line==Ofline){
// printf(" before %d ",total);
atLine = total;
}
if(line==(Ofline+1)){
// printf(" after %d ",total);
afterLine = total-atLine;
}
// printf(" line is %d ",line);
line++;
}
total++;
}
fseek(df, 0L, SEEK_SET);
if(afterLine==0){
return (total-atLine-1);
}
else
{
return (afterLine-1);
}
}
用途:
FILE* fp = fopen("path-to-file" , "r");
if(fp!=NULL){
printf(" %d",getLengthOfLine(fp,5));
}
【讨论】: