LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 605|回复: 3

能否能过 fcntl() 获取文本文体的行数??

[复制链接]
发表于 2005-1-31 16:20:30 | 显示全部楼层 |阅读模式
不想手动去统计文件中'\n'的数量,因为文件很多,这样可能效率不高。请问能不能用fcntl()这样的函数实现这个功能。

不知道 wc 程序是如何得到文件行数的???

谢谢
发表于 2005-1-31 16:55:53 | 显示全部楼层
fcntl()没有用过!不过实现这种功能的方法很多!

对于unix文本结尾处只有个'\n'
对于windows文本结尾处有'\r\n'!      这个是关键要注意!

知道了上面的东西后,你用什么函数来做都行,比如用fgetc()来读入每个字符,根据条件比较!就ok了!
回复 支持 反对

使用道具 举报

发表于 2005-1-31 18:03:55 | 显示全部楼层
估计没啥好办法了吧.这段是在网在找的
/*  Example: Word Counting
        Source: K&R2, p.20
*/

#include <stdio.h>

#define IN 1 /* inside a word */
#define OUT 2 /* outside a word */

/* count lines, words, and characters in input */

void main () {
        int c, nl, nw, nc, state;

        state = OUT;
        nl = nw = nc = 0;
        while ((c = getchar()) != EOF) {
                ++nc;
                if (c == '\n')
                        ++nl;
                if (c == ' ' || c == '\n' || c == '\t')
                        state = OUT;
                else if (state == OUT) {
                        state = IN;
                        ++nw;
                }               
        }
        printf("%d %d %d\n", nl, nw, nc);
}
回复 支持 反对

使用道具 举报

发表于 2005-1-31 18:12:06 | 显示全部楼层
4.4bsd的wc也是统计\n的.


  1. /*
  2. * Copyright (c) 1980, 1987, 1991, 1993
  3. *        The Regents of the University of California.  All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. *    notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. *    notice, this list of conditions and the following disclaimer in the
  12. *    documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. *    must display the following acknowledgement:
  15. *        This product includes software developed by the University of
  16. *        California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. *    may be used to endorse or promote products derived from this software
  19. *    without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */

  33. #ifndef lint
  34. static char copyright[] =
  35. "@(#) Copyright (c) 1980, 1987, 1991, 1993\n\
  36.         The Regents of the University of California.  All rights reserved.\n";
  37. #endif /* not lint */

  38. #ifndef lint
  39. static char sccsid[] = "@(#)wc.c        8.2 (Berkeley) 5/2/95";
  40. #endif /* not lint */

  41. #include <sys/param.h>
  42. #include <sys/stat.h>
  43. #include <fcntl.h>
  44. #include <unistd.h>
  45. #include <errno.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <ctype.h>

  50. u_long tlinect, twordct, tcharct;
  51. int doline, doword, dochar;

  52. void cnt __P((char *));
  53. void err __P((const char *, ...));
  54. void usage __P((void));

  55. int
  56. main(argc, argv)
  57.         int argc;
  58.         char *argv[];
  59. {
  60.         register int ch;
  61.         int total;

  62.         while ((ch = getopt(argc, argv, "lwc")) != EOF)
  63.                 switch((char)ch) {
  64.                 case 'l':
  65.                         doline = 1;
  66.                         break;
  67.                 case 'w':
  68.                         doword = 1;
  69.                         break;
  70.                 case 'c':
  71.                         dochar = 1;
  72.                         break;
  73.                 case '?':
  74.                 default:
  75.                         usage();
  76.                 }
  77.         argv += optind;
  78.         argc -= optind;

  79.         /* Wc's flags are on by default. */
  80.         if (doline + doword + dochar == 0)
  81.                 doline = doword = dochar = 1;

  82.         total = 0;
  83.         if (!*argv) {
  84.                 cnt(NULL);
  85.                 (void)printf("\n");
  86.         }
  87.         else do {
  88.                 cnt(*argv);
  89.                 (void)printf(" %s\n", *argv);
  90.                 ++total;
  91.         } while(*++argv);

  92.         if (total > 1) {
  93.                 if (doline)
  94.                         (void)printf(" %7ld", tlinect);
  95.                 if (doword)
  96.                         (void)printf(" %7ld", twordct);
  97.                 if (dochar)
  98.                         (void)printf(" %7ld", tcharct);
  99.                 (void)printf(" total\n");
  100.         }
  101.         exit(0);
  102. }

  103. void
  104. cnt(file)
  105.         char *file;
  106. {
  107.         register u_char *p;
  108.         register short gotsp;
  109.         register int ch, len;
  110.         register u_long linect, wordct, charct;
  111.         struct stat sb;
  112.         int fd;
  113.         u_char buf[MAXBSIZE];

  114.         fd = STDIN_FILENO;
  115.         linect = wordct = charct = 0;
  116.         if (file) {
  117.                 if ((fd = open(file, O_RDONLY, 0)) < 0)
  118.                         err("%s: %s", file, strerror(errno));
  119.                 if (doword)
  120.                         goto word;
  121.                 /*
  122.                  * Line counting is split out because it's a lot faster to get
  123.                  * lines than to get words, since the word count requires some
  124.                  * logic.
  125.                  */
  126.                 if (doline) {
  127.                         while (len = read(fd, buf, MAXBSIZE)) {
  128.                                 if (len == -1)
  129.                                         err("%s: %s", file, strerror(errno));
  130.                                 charct += len;
  131.                                 for (p = buf; len--; ++p)
  132.                                         if (*p == '\n')
  133.                                                 ++linect;
  134.                         }
  135.                         tlinect += linect;
  136.                         (void)printf(" %7lu", linect);
  137.                         if (dochar) {
  138.                                 tcharct += charct;
  139.                                 (void)printf(" %7lu", charct);
  140.                         }
  141.                         (void)close(fd);
  142.                         return;
  143.                 }
  144.                 /*
  145.                  * If all we need is the number of characters and it's a
  146.                  * regular or linked file, just stat the puppy.
  147.                  */
  148.                 if (dochar) {
  149.                         if (fstat(fd, &sb))
  150.                                 err("%s: %s", file, strerror(errno));
  151.                         if (S_ISREG(sb.st_mode)) {
  152.                                 (void)printf(" %7qu", sb.st_size);
  153.                                 tcharct += sb.st_size;
  154.                                 (void)close(fd);
  155.                                 return;
  156.                         }
  157.                 }
  158.         }

  159.         /* Do it the hard way... */
  160. word:        for (gotsp = 1; len = read(fd, buf, MAXBSIZE);) {
  161.                 if (len == -1)
  162.                         err("%s: %s", file, strerror(errno));
  163.                 /*
  164.                  * This loses in the presence of multi-byte characters.
  165.                  * To do it right would require a function to return a
  166.                  * character while knowing how many bytes it consumed.
  167.                  */
  168.                 charct += len;
  169.                 for (p = buf; len--;) {
  170.                         ch = *p++;
  171.                         if (ch == '\n')
  172.                                 ++linect;
  173.                         if (isspace(ch))
  174.                                 gotsp = 1;
  175.                         else if (gotsp) {
  176.                                 gotsp = 0;
  177.                                 ++wordct;
  178.                         }
  179.                 }
  180.         }
  181.         if (doline) {
  182.                 tlinect += linect;
  183.                 (void)printf(" %7lu", linect);
  184.         }
  185.         if (doword) {
  186.                 twordct += wordct;
  187.                 (void)printf(" %7lu", wordct);
  188.         }
  189.         if (dochar) {
  190.                 tcharct += charct;
  191.                 (void)printf(" %7lu", charct);
  192.         }
  193.         (void)close(fd);
  194. }

  195. void
  196. usage()
  197. {
  198.         (void)fprintf(stderr, "usage: wc [-clw] [files]\n");
  199.         exit(1);
  200. }

  201. #if __STDC__
  202. #include <stdarg.h>
  203. #else
  204. #include <varargs.h>
  205. #endif

  206. void
  207. #if __STDC__
  208. err(const char *fmt, ...)
  209. #else
  210. err(fmt, va_alist)
  211.         char *fmt;
  212.         va_dcl
  213. #endif
  214. {
  215.         va_list ap;
  216. #if __STDC__
  217.         va_start(ap, fmt);
  218. #else
  219.         va_start(ap);
  220. #endif
  221.         (void)fprintf(stderr, "wc: ");
  222.         (void)vfprintf(stderr, fmt, ap);
  223.         va_end(ap);
  224.         (void)fprintf(stderr, "\n");
  225.         exit(1);
  226.         /* NOTREACHED */
  227. }

复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表