【问题标题】:Finding line size of each row in a text file查找文本文件中每一行的行大小
【发布时间】:2011-01-09 09:05:03
【问题描述】:

如何计算每行中的字符数或数字数?是否有类似 EOF 的东西更像是行尾?

【问题讨论】:

    标签: c


    【解决方案1】:

    您可以遍历行中的每个字符并不断增加计数器,直到遇到行尾 ('\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;
    }
    

    【讨论】:

    • 您实际上并不需要逐个字符地获取新行的索引。您可以使用 strcspn() 来查找 '\n' 的索引。 (见stackoverflow.com/questions/4824/string-indexof-function-in-c
    • strcspn() 和 strspn() 不从文件中读取。要使用它们,您必须将整行读入一个字符串,然后重新遍历它以找到 '\n' 字符。这效率较低。当然,这要看MRP是怎么做他的文件IO代码的。
    【解决方案2】:

    关于逐行读取文件,看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
    

    但由于您不太可能使用仅使用回车的表示形式,因此寻找换行符应该没问题。

    【讨论】:

    • 所以你可以循环直到 char = \n
    • 文件 *in; in = fopen ("numbers.txt", "r"); if ( in != NULL ) { 我是否使用 fget 直到 \n ?
    • 对,fgetc 获取单个字符。
    • @danben:如果文件以文本模式打开,底层库将负责将换行符表示为 '\n',即使在 Windows 上也是如此。
    【解决方案3】:

    如果您以文本模式打开文件,即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.. 我不确定这是 Var 还是 C 使用的命令。
    • @MRP: SIZE 是一个方便的正整数值,可以是预处理器宏或幻数。我没有给你一个完整的代码,因为我不确定这是否是一个家庭作业问题。 :-)
    • 好吧,如果 SIZE 是我输入的数字.. 我需要它的东西不会起作用,因为我不知道尺寸..
    • 例如在一行中可能是 10 个整数或 20 个整数
    • 不,假设SIZE 是128。然后,正如我在fgets() 之后的评论所说,如果buf 表示的字符串不包含换行符,则表示您的行更长超过 127 个字符。在这种情况下,您再次调用fgets(),并将count 增加127。因此,上面的代码将毫无问题地读取长行,并正确确定一行中的字符数。
    【解决方案4】:

    最初的问题是如何获取“每一行”中的字符数(给定一行?还是当前行?),而答案大多给出了如何确定文件中第一行长度的解决方案.可以轻松地应用其中一些来确定当前行的长度(无需事先猜测缓冲区的最大长度)。

    但是,在实践中通常需要的是文件中任何行的最大长度。然后可以保留一个缓冲区并使用 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;
    

    注意:在实践中,为最大长度设置一个上限就足够了。一个肮脏的解决方案是使用文件大小作为最大行长度的上限。

    【讨论】:

    • 这应该是公认的解决方案。据我所知,Sam 的解决方案只获取文件第一行的长度。我也喜欢你的肮脏技巧。
    【解决方案5】:

    \n 是 C 中的换行符。在其他语言中,例如 C#,您可以使用类似 C# 的Environment.EndLine 来克服平台困难。

    如果您已经知道您的字符串是一行(我们称之为 line),请使用strlen(line) 获取其中的字符数。如果以 '\n' 结尾,则减 1。

    如果字符串中有换行符,您需要将其拆分为换行符,然后在每个子字符串上调用strlen()

    【讨论】:

    • 他没有字符串,他有文件。
    【解决方案6】:

    这是一个简单的算法:

    你需要

    • 文件流 (FILE),
    • 行号,您希望大小为 (int)

    返回

    • 给定行中的总字符

    功能:

      #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));
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2014-02-26
      • 2011-08-10
      • 2018-04-21
      • 2021-03-25
      相关资源
      最近更新 更多