Commande Unix wc en C

Commande Unix wc en C - C - Programmation

Marsh Posté le 20-11-2005 à 20:28:54    

Bonjour
 
Je voudrais un programme en C qui est identique a la commande wc.
 
Il faut que ce programme compte le nombre de caracteres, de mots et de lignes d'un fichier passé en paramètre.
 
Exemple :  
wc fichier.txt
nb de caracteres : 658
nb de mots : 137
nb de lignes : 32
 
Merci pour votre aide
 

Reply

Marsh Posté le 20-11-2005 à 20:28:54   

Reply

Marsh Posté le 20-11-2005 à 20:31:42    

ben alors tu veux quoi qu on te le code du debut a la fin

Reply

Marsh Posté le 20-11-2005 à 20:35:29    

Cela ressemble à un devoir d'étudiant.
Il faudrait que tu cherches par toi-même, et que tu ne viennes demander de l'aide qu'après avoir étudier le problème, avoir commencer, et être bloquer par un obstacle que tu peux décrire.
 
Cependant, j'ai trouvé le programme suivant dans mes tiroirs :

Code :
  1. /*
  2.    File wc.c - a sample word count program
  3.    Written and submitted to public domain by Jay Elkes
  4.    April, 1992
  5. */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. int main (int argc, char *argv[])
  9. {
  10.       FILE *infileptr;
  11.       char infile[80];
  12.       long int nl = 0;
  13.       long int nc = 0;
  14.       long int nw = 0;
  15.       int state = 0;
  16.       const int  NEWLINE = '\n';
  17.       int  c;
  18. /*  The program name itself is the first command line arguement so we
  19.     ignore it (argv[0]) when showing user entered parameters. */
  20.       switch (argc - 1)
  21.       {
  22.       case (0):
  23.             printf("no parameters\n" );
  24.             return 12;
  25.       case (1):
  26.             break;
  27.       default:
  28.             printf("too many parameters\n" );
  29.             return 12;
  30.       }
  31.       strcpy(infile,argv[1]);
  32.       infileptr = fopen(infile,"rb" );
  33.       if (infileptr == NULL)
  34.       {
  35.             printf("Cannot open %s\n",infile);
  36.             return 12;
  37.       }
  38.       while ((c = getc(infileptr)) != EOF)
  39.       {
  40.             ++nc;
  41.             if (c == NEWLINE)
  42.                   ++nl;
  43.             if (isspace(c))
  44.                   state = 0;
  45.             else if (state == 0)
  46.             {
  47.                   state = 1;
  48.                   ++nw;
  49.             }
  50.       }
  51.       /* Final Housekeeping */
  52.       printf("%ld Lines, %ld Words, %ld Characters", nl, nw, nc);
  53.       return 0;
  54. }

Reply

Marsh Posté le 20-11-2005 à 20:36:48    

T'ouvres le fichier, tu lis avec fgets() par exemple, à chaque fin de boucle t'incrémentes le nombre de lignes.
Le nombre de caractères tu peux prendre strlen de la ligne, et un mot c'est separé par un espace donc tu vois avec ça, tu fermes le fichier et t'affiche tes résultats.
 
Ou alors tu fait un popen sur wc et tu affiche les résultats  :o
 
Edit: ou alors tu regardes au dessus..


Message édité par Flaie le 20-11-2005 à 20:37:50

---------------
Always wear a camera!
Reply

Marsh Posté le 20-11-2005 à 20:36:53    

EDIT : multi-grillage, donc inutile d'en rajouter :o


Message édité par Elmoricq le 20-11-2005 à 20:39:04
Reply

Marsh Posté le 20-11-2005 à 22:40:06    

JustOne72 a écrit :

Je voudrais un programme en C qui est identique a la commande wc.


http://www.ecranlarge.com/images/cinema/fiches/affiches/3ce4079abe760a7f8eb4ee253072adab.jpg
 
Tu as oublié

  • Soit de poster le code que tu as ecrit en indiquant ce qui ne va pas.
  • Soit de donner l'email de ton prof pour qu'on lui envoie le code directement...
  • Soit de brancher ton cerveau http://flight.engr.ucdavis.edu/~eamayda/images/brain_plugged.png



Message édité par Emmanuel Delahaye le 20-11-2005 à 23:03:21

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-11-2005 à 23:42:55    

Code :
  1. /* wc - print the number of bytes, words, and lines in files
  2.    Copyright (C) 85, 91, 1995-2002 Free Software Foundation, Inc.
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.    This program is distributed in the hope that it will be useful,
  8.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.    GNU General Public License for more details.
  11.    You should have received a copy of the GNU General Public License
  12.    along with this program; if not, write to the Free Software Foundation,
  13.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  14. /* Written by Paul Rubin, phr@ocf.berkeley.edu
  15.    and David MacKenzie, djm@gnu.ai.mit.edu. */
  16. #include <config.h>
  17. #if HAVE_INTTYPES_H
  18. # include <inttypes.h>
  19. #endif
  20. #include <stdio.h>
  21. #include <getopt.h>
  22. #include <sys/types.h>
  23. /* Get mbstate_t, mbrtowc(), wcwidth().  */
  24. #if HAVE_WCHAR_H
  25. #include <wchar.h>
  26. #endif
  27. /* Get iswprint(), iswspace().  */
  28. #if HAVE_WCTYPE_H
  29. # include <wctype.h>
  30. #ndif
  31. #if !defined iswprint && !HAVE_ISWPRINT
  32. # define iswprint(wc) 1
  33. #endif
  34. #if !defined iswspace && !HAVE_ISWSPACE
  35. #define iswspace(wc) \
  36.     ((wc) == (unsigned char) (wc) && ISSPACE ((unsigned char) (wc)))
  37. #endif
  38. /* Include this after wctype.h so that we `#undef' ISPRINT
  39.    (from Solaris's euc.h, from widec.h, from wctype.h) before
  40.    redefining and using it. */
  41. #include "system.h"
  42. #include "closeout.h"
  43. #include "error.h"
  44. #include "human.h"
  45. #include "safe-read.h"
  46. /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t.  */
  47. #if HAVE_MBRTOWC && defined mbstate_t
  48. #define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
  49. #endif
  50. #ifndef HAVE_DECL_WCWIDTH
  51. "this configure-time declaration test was not run"
  52. #endif
  53. #if !HAVE_DECL_WCWIDTH
  54. extern int wcwidth ();
  55. #endif
  56. /* If wcwidth() doesn't exist, assume all printable characters have
  57.    width 1.  */
  58. #if !defined wcwidth && !HAVE_WCWIDTH
  59. #define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)
  60. #endif
  61. /* The official name of this program (e.g., no `g' prefix).  */
  62. #define PROGRAM_NAME "wc"
  63. #define AUTHORS N_ ("Paul Rubin and David MacKenzie" )
  64. /* Size of atomic reads. */
  65. #define BUFFER_SIZE (16 * 1024)
  66. /* The name this program was run with. */
  67. char *program_name;
  68. /* Cumulative number of lines, words, chars and bytes in all files so far.
  69.    max_line_length is the maximum over all files processed so far.  */
  70. static uintmax_t total_lines;
  71. static uintmax_t total_words;
  72. static uintmax_t total_chars;
  73. static uintmax_t total_bytes;
  74. static uintmax_t max_line_length;
  75. /* Which counts to print. */
  76. static int print_lines, print_words, print_chars, print_bytes;
  77. static int print_linelength;
  78. /* Nonzero if we have ever read the standard input. */
  79. static int have_read_stdin;
  80. /* The error code to return to the system. */
  81. static int exit_status;
  82. /* If nonzero, do not line up columns but instead separate numbers by
  83.    a single space as specified in Single Unix Specification and POSIX. */
  84. static int posixly_correct;
  85. static struct option const longopts[] =
  86. {
  87.   {"bytes", no_argument, NULL, 'c'},
  88.   {"chars", no_argument, NULL, 'm'},
  89.   {"lines", no_argument, NULL, 'l'},
  90.   {"words", no_argument, NULL, 'w'},
  91.   {"max-line-length", no_argument, NULL, 'L'},
  92.   {GETOPT_HELP_OPTION_DECL},
  93.   {GETOPT_VERSION_OPTION_DECL},
  94.   {NULL, 0, NULL, 0}
  95. };
  96. void
  97. usage (int status)
  98. {
  99.   if (status != 0)
  100.     fprintf (stderr, _("Try `%s --help' for more information.\n" ),
  101.      program_name);
  102.   else
  103.     {
  104.       printf (_("\
  105. Usage: %s [OPTION]... [FILE]...\n\
  106. " ),
  107.       program_name);
  108.       fputs (_("\
  109. Print byte, word, and newline counts for each FILE, and a total line if\n\
  110. more than one FILE is specified.  With no FILE, or when FILE is -,\n\
  111. read standard input.\n\
  112.   -c, --bytes            print the byte counts\n\
  113.   -m, --chars            print the character counts\n\
  114.   -l, --lines            print the newline counts\n\
  115. " ), stdout);
  116.       fputs (_("\
  117.   -L, --max-line-length  print the length of the longest line\n\
  118.   -w, --words            print the word counts\n\
  119. " ), stdout);
  120.       fputs (HELP_OPTION_DESCRIPTION, stdout);
  121.       fputs (VERSION_OPTION_DESCRIPTION, stdout);
  122.       printf (_("\nReport bugs to <%s>.\n" ), PACKAGE_BUGREPORT);
  123.     }
  124.   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  125. }
  126. static void
  127. write_counts (uintmax_t lines,
  128.       uintmax_t words,
  129.       uintmax_t chars,
  130.       uintmax_t bytes,
  131.       uintmax_t linelength,
  132.       const char *file)
  133. {
  134.   char buf[LONGEST_HUMAN_READABLE + 1];
  135.   char const *space = "";
  136.   char const *format_int = (posixly_correct ? "%s" : "%7s" );
  137.   char const *format_sp_int = (posixly_correct ? "%s%s" : "%s%7s" );
  138.   if (print_lines)
  139.     {
  140.       printf (format_int, human_readable (lines, buf, 1, 1));
  141.       space = " ";
  142.     }
  143.   if (print_words)
  144.     {
  145.       printf (format_sp_int, space, human_readable (words, buf, 1, 1));
  146.       space = " ";
  147.     }
  148.   if (print_chars)
  149.     {
  150.       printf (format_sp_int, space, human_readable (chars, buf, 1, 1));
  151.       space = " ";
  152.     }
  153.   if (print_bytes)
  154.     {
  155.       printf (format_sp_int, space, human_readable (bytes, buf, 1, 1));
  156.       space = " ";
  157.     }
  158.   if (print_linelength)
  159.     {
  160.       printf (format_sp_int, space, human_readable (linelength, buf, 1, 1));
  161.     }
  162.   if (*file)
  163.     printf (" %s", file);
  164.   putchar ('\n');
  165. }
  166. static void
  167. wc (int fd, const char *file)
  168. {
  169.   char buf[BUFFER_SIZE + 1];
  170.   ssize_t bytes_read;
  171.   uintmax_t lines, words, chars, bytes, linelength;
  172.   int count_bytes, count_chars, count_complicated;
  173.   lines = words = chars = bytes = linelength = 0;
  174.   /* If in the current locale, chars are equivalent to bytes, we prefer
  175.      counting bytes, because that's easier.  */
  176. #if HAVE_MBRTOWC && (MB_LEN_MAX > 1)
  177.   if (MB_CUR_MAX > 1)
  178.     {
  179.       count_bytes = print_bytes;
  180.       count_chars = print_chars;
  181.     }
  182.   else
  183. #endif
  184.     {
  185.       count_bytes = print_bytes + print_chars;
  186.       count_chars = 0;
  187.     }
  188.   count_complicated = print_words + print_linelength;
  189.   /* We need binary input, since `wc' relies on `lseek' and byte counts.  */
  190.   SET_BINARY (fd);
  191.   /* When counting only bytes, save some line- and word-counting
  192.      overhead.  If FD is a `regular' Unix file, using lseek is enough
  193.      to get its `size' in bytes.  Otherwise, read blocks of BUFFER_SIZE
  194.      bytes at a time until EOF.  Note that the `size' (number of bytes)
  195.      that wc reports is smaller than stats.st_size when the file is not
  196.      positioned at its beginning.  That's why the lseek calls below are
  197.      necessary.  For example the command
  198.      `(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
  199.      should make wc report `0' bytes.  */
  200.   if (count_bytes && !count_chars && !print_lines && !count_complicated)
  201.     {
  202.       off_t current_pos, end_pos;
  203.       struct stat stats;
  204.       if (fstat (fd, &stats) == 0 && S_ISREG (stats.st_mode)
  205.   && (current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
  206.   && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
  207. {
  208.   off_t diff;
  209.   /* Be careful here.  The current position may actually be
  210.      beyond the end of the file.  As in the example above.  */
  211.   bytes = (diff = end_pos - current_pos) < 0 ? 0 : diff;
  212. }
  213.       else
  214. {
  215.   while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
  216.     {
  217.       bytes += bytes_read;
  218.     }
  219.   if (bytes_read < 0)
  220.     {
  221.       error (0, errno, "%s", file);
  222.       exit_status = 1;
  223.     }
  224. }
  225.     }
  226.   else if (!count_chars && !count_complicated)
  227.     {
  228.       /* Use a separate loop when counting only lines or lines and bytes --
  229.  but not chars or words.  */
  230.       while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
  231. {
  232.   register char *p = buf;
  233.   while ((p = memchr (p, '\n', (buf + bytes_read) - p)))
  234.     {
  235.       ++p;
  236.       ++lines;
  237.     }
  238.   bytes += bytes_read;
  239. }
  240.       if (bytes_read < 0)
  241. {
  242.   error (0, errno, "%s", file);
  243.   exit_status = 1;
  244. }
  245.     }
  246. #if HAVE_MBRTOWC && (MB_LEN_MAX > 1)
  247. # define SUPPORT_OLD_MBRTOWC 1
  248.   else if (MB_CUR_MAX > 1)
  249.     {
  250.       int in_word = 0;
  251.       uintmax_t linepos = 0;
  252.       mbstate_t state;
  253.       uintmax_t last_error_line = 0;
  254.       int last_error_errno = 0;
  255. # if SUPPORT_OLD_MBRTOWC
  256.       /* Back-up the state before each multibyte character conversion and
  257.  move the last incomplete character of the buffer to the front
  258.  of the buffer.  This is needed because we don't know whether
  259.  the `mbrtowc' function updates the state when it returns -2, -
  260.  this is the ISO C 99 and glibc-2.2 behaviour - or not - amended
  261.  ANSI C, glibc-2.1 and Solaris 2.7 behaviour.  We don't have an
  262.  autoconf test for this, yet.  */
  263.       int prev = 0; /* number of bytes carried over from previous round */
  264. # else
  265.       const int prev = 0;
  266. # endif
  267.       memset (&state, 0, sizeof (mbstate_t));
  268.       while ((bytes_read = safe_read (fd, buf + prev, BUFFER_SIZE - prev)) > 0)
  269. {
  270.   const char *p;
  271. # if SUPPORT_OLD_MBRTOWC
  272.   mbstate_t backup_state;
  273. # endif
  274.   bytes += bytes_read;
  275.   p = buf;
  276.   bytes_read += prev;
  277.   do
  278.     {
  279.       wchar_t wide_char;
  280.       size_t n;
  281. # if SUPPORT_OLD_MBRTOWC
  282.       backup_state = state;
  283. # endif
  284.       n = mbrtowc (&wide_char, p, bytes_read, &state);
  285.       if (n == (size_t) -2)
  286.  {
  287. # if SUPPORT_OLD_MBRTOWC
  288.    state = backup_state;
  289. # endif
  290.    break;
  291.  }
  292.       if (n == (size_t) -1)
  293.  {
  294.    /* Signal repeated errors only once per line.  */
  295.    if (!(lines + 1 == last_error_line
  296.   && errno == last_error_errno))
  297.      {
  298.        char hr_buf[LONGEST_HUMAN_READABLE + 1];
  299.        last_error_line = lines + 1;
  300.        last_error_errno = errno;
  301.        error (0, errno, "%s:%s", file,
  302.        human_readable (lines + 1, hr_buf, 1, 1));
  303.      }
  304.    p++;
  305.    bytes_read--;
  306.  }
  307.       else
  308.  {
  309.    if (n == 0)
  310.      {
  311.        wide_char = 0;
  312.        n = 1;
  313.      }
  314.    p += n;
  315.    bytes_read -= n;
  316.    chars++;
  317.    switch (wide_char)
  318.      {
  319.      case '\n':
  320.        lines++;
  321.        /* Fall through. */
  322.      case '\r':
  323.      case '\f':
  324.        if (linepos > linelength)
  325.   linelength = linepos;
  326.        linepos = 0;
  327.        goto mb_word_separator;
  328.      case '\t':
  329.        linepos += 8 - (linepos % 8);
  330.        goto mb_word_separator;
  331.      case ' ':
  332.        linepos++;
  333.        /* Fall through. */
  334.      case '\v':
  335.      mb_word_separator:
  336.        if (in_word)
  337.   {
  338.     in_word = 0;
  339.     words++;
  340.   }
  341.        break;
  342.      default:
  343.        if (iswprint (wide_char))
  344.   {
  345.     int width = wcwidth (wide_char);
  346.     if (width > 0)
  347.       linepos += width;
  348.     if (iswspace (wide_char))
  349.       goto mb_word_separator;
  350.     in_word = 1;
  351.   }
  352.        break;
  353.      }
  354.  }
  355.     }
  356.   while (bytes_read > 0);
  357. # if SUPPORT_OLD_MBRTOWC
  358.   if (bytes_read > 0)
  359.     {
  360.       if (bytes_read == BUFFER_SIZE)
  361.  {
  362.    /* Encountered a very long redundant shift sequence.  */
  363.    p++;
  364.    bytes_read--;
  365.  }
  366.       memmove (buf, p, bytes_read);
  367.     }
  368.   prev = bytes_read;
  369. # endif
  370. }
  371.       if (bytes_read < 0)
  372. {
  373.   error (0, errno, "%s", file);
  374.   exit_status = 1;
  375. }
  376.       if (linepos > linelength)
  377. linelength = linepos;
  378.       if (in_word)
  379. words++;
  380.     }
  381. #endif
  382.   else
  383.     {
  384.       int in_word = 0;
  385.       uintmax_t linepos = 0;
  386.       while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
  387. {
  388.   const char *p = buf;
  389.   bytes += bytes_read;
  390.   do
  391.     {
  392.       switch (*p++)
  393.  {
  394.  case '\n':
  395.    lines++;
  396.    /* Fall through. */
  397.  case '\r':
  398.  case '\f':
  399.    if (linepos > linelength)
  400.      linelength = linepos;
  401.    linepos = 0;
  402.    goto word_separator;
  403.  case '\t':
  404.    linepos += 8 - (linepos % 8);
  405.    goto word_separator;
  406.  case ' ':
  407.    linepos++;
  408.    /* Fall through. */
  409.  case '\v':
  410.  word_separator:
  411.    if (in_word)
  412.      {
  413.        in_word = 0;
  414.        words++;
  415.      }
  416.    break;
  417.  default:
  418.    if (ISPRINT ((unsigned char) p[-1]))
  419.      {
  420.        linepos++;
  421.        if (ISSPACE ((unsigned char) p[-1]))
  422.   goto word_separator;
  423.        in_word = 1;
  424.      }
  425.    break;
  426.  }
  427.     }
  428.   while (--bytes_read);
  429. }
  430.       if (bytes_read < 0)
  431. {
  432.   error (0, errno, "%s", file);
  433.   exit_status = 1;
  434. }
  435.       if (linepos > linelength)
  436. linelength = linepos;
  437.       if (in_word)
  438. words++;
  439.     }
  440.   if (count_chars < print_chars)
  441.     chars = bytes;
  442.   write_counts (lines, words, chars, bytes, linelength, file);
  443.   total_lines += lines;
  444.   total_words += words;
  445.   total_chars += chars;
  446.   total_bytes += bytes;
  447.   if (linelength > max_line_length)
  448.     max_line_length = linelength;
  449. }
  450. static void
  451. wc_file (const char *file)
  452. {
  453.   if (STREQ (file, "-" ))
  454.     {
  455.       have_read_stdin = 1;
  456.       wc (0, file);
  457.     }
  458.   else
  459.     {
  460.       int fd = open (file, O_RDONLY);
  461.       if (fd == -1)
  462. {
  463.   error (0, errno, "%s", file);
  464.   exit_status = 1;
  465.   return;
  466. }
  467.       wc (fd, file);
  468.       if (close (fd))
  469. {
  470.   error (0, errno, "%s", file);
  471.   exit_status = 1;
  472. }
  473.     }
  474. }
  475. int
  476. main (int argc, char **argv)
  477. {
  478.   int optc;
  479.   int nfiles;
  480.   program_name = argv[0];
  481.   setlocale (LC_ALL, "" );
  482.   bindtextdomain (PACKAGE, LOCALEDIR);
  483.   textdomain (PACKAGE);
  484.   atexit (close_stdout);
  485.   exit_status = 0;
  486.   posixly_correct = (getenv ("POSIXLY_CORRECT" ) != NULL);
  487.   print_lines = print_words = print_chars = print_bytes = print_linelength = 0;
  488.   total_lines = total_words = total_chars = total_bytes = max_line_length = 0;
  489.   while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1)
  490.     switch (optc)
  491.       {
  492.       case 0:
  493. break;
  494.       case 'c':
  495. print_bytes = 1;
  496. break;
  497.       case 'm':
  498. print_chars = 1;
  499. break;
  500.       case 'l':
  501. print_lines = 1;
  502. break;
  503.       case 'w':
  504. print_words = 1;
  505. break;
  506.       case 'L':
  507. print_linelength = 1;
  508. break;
  509.       case_GETOPT_HELP_CHAR;
  510.       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
  511.       default:
  512. usage (1);
  513.       }
  514.   if (print_lines + print_words + print_chars + print_bytes + print_linelength
  515.       == 0)
  516.     print_lines = print_words = print_bytes = 1;
  517.   nfiles = argc - optind;
  518.   if (nfiles == 0)
  519.     {
  520.       have_read_stdin = 1;
  521.       wc (0, "" );
  522.     }
  523.   else
  524.     {
  525.       for (; optind < argc; ++optind)
  526. wc_file (argv[optind]);
  527.       if (nfiles > 1)
  528. write_counts (total_lines, total_words, total_chars, total_bytes,
  529.        max_line_length, _("total" ));
  530.     }
  531.   if (have_read_stdin && close (0))
  532.     error (EXIT_FAILURE, errno, "-" );
  533.   exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  534. }


 
de rien [:kbchris]


Message édité par masklinn le 20-11-2005 à 23:44:01

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 21-11-2005 à 01:21:12    

:lol:  596 lignes pour compter lignes, caracteres et mots !! [:petrus75]

Reply

Marsh Posté le 21-11-2005 à 07:01:55    

gocho a écrit :

:lol:  596 lignes pour compter lignes, caracteres et mots !! [:petrus75]


 
Euh, tu l'as lu au moins ? Et compris ?   [:pingouino]  
 
Non parce que se référer au nombre de lignes d'un source qui compte autant de commentaires, de directives de compilation et de fonctions type "j'affiche l'aide de mon programme", c'est un peu stupide hein.  
 
Qui plus est ce programme compte n fichiers, il évite les cas tordus, et est certainement bien plus rapide que la boucle avec fgetc() [:petrus75]
 
Tiens d'ailleurs c'est le vrai wc celui-là. Celui qui va pas me mettre 15 ans à me sortir le nombre de bytes  d'un fichier de 150Mo  [:petrus75]  
 
Bon évidemment, pour le posteur initial et son devoir d'étudiant, c'est de l'overkill, mais bon le but de Masklinn c'était pas vraiment de l'aider non plus.

Message cité 2 fois
Message édité par Elmoricq le 21-11-2005 à 07:13:43
Reply

Marsh Posté le 21-11-2005 à 10:29:14    

Elmoricq a écrit :

Celui qui va pas me mettre 15 ans à me sortir le nombre de bytes  d'un fichier de 150Mo


Justement, je me suis posé la question, et voici quelques résultats intéressants (PC Celeron 2.8 GHz/XP)
Le fichier de test est un gros .zip de 219 Mo (donc lecture en binaire)
 
Test 1 met en oeuvre fgetc()

     while ((c = fgetc (fp)) != EOF)


Test 2 met en oeuvre fread() avec un buffer de BUFSIZ et une lecture par blocs de BUFSIZ bytes.

     while ((n = fread (buf, sizeof buf, 1, fp)) > 0)


Test 3 met en oeuvre fread() avec un buffer de BUFSIZ et BUFSIZ lectures de un byte.

     while ((n = fread (buf, 1, sizeof buf, fp)) > 0)


Résultat :  


g:/asma.zip has 230493897 bytes
"Test 1" done in 105.61 s
g:/asma.zip has 230493696 bytes (at least)
"Test 2" done in 0.58 s
g:/asma.zip has 230493897 bytes
"Test 3" done in 0.56 s


Je vois déjà les cris 'haro sur la lecture byte par byte" etc... Ok?  
 
Poursuivons en inversant les tests :  


g:/asma.zip has 230493696 bytes (at least)
"Test 2" done in 80.92 s
g:/asma.zip has 230493897 bytes
"Test 1" done in 50.25 s
g:/asma.zip has 230493897 bytes
"Test 3" done in 0.61 s


Les choses ne sont plus si claires...
D'autres séquences montrent d'autres résultats.  


g:/asma.zip has 230493897 bytes
"Test 3" done in 75.41 s
g:/asma.zip has 230493897 bytes
"Test 1" done in 43.48 s
g:/asma.zip has 230493696 bytes (at least)
"Test 2" done in 0.52 s


Conclusion, seul le test joué en premier est concluant. Ensuite, les caches faussent complètement les résultats. Se méfier des conclusions hatives, et décrire ses conditions de test...
 
Le rapport entre fgetc() et fread() n'est finalement de moins de 1 à 2...


Message édité par Emmanuel Delahaye le 21-11-2005 à 10:45:57

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-11-2005 à 10:29:14   

Reply

Marsh Posté le 21-11-2005 à 10:44:18    

Oui mais si on se contente de compter les bytes avec wc, et si on n'est pas dans un cas tordu, il utilise lseek ce qui est quand même plus rapide qu'un parcours exhaustif.
 
Pour un fichier de plus de 200Mo, il me met 3 ou 4s pour me sortir le nombre de bytes utilisés, c'est plutôt raisonnable.
 
Et puis on voit quand même que la méthode de lecture par bloc est plus rapide, de "20% environ"  sur ton seul exemple, ce n'est pas négligeable ; et je pense qu'on peut encore améliorer ce temps avec une taille de buffer correspondant à la taille du fichier (genre avec 200Mo de fichier, un buffer de 1024 c'est un peu petit).
Mais c'est sûr que le cache fausse carrément les résultats. Et j'ai mis "20% environ" entre guillemets parce que d'autres facteurs interviennent, genre ce que fait le disque dur à ce moment-là, ce que le système décide de t'accorder comme temps, la fragmentation du fichier etc...


Message édité par Elmoricq le 21-11-2005 à 10:48:05
Reply

Marsh Posté le 21-11-2005 à 10:45:49    

Elmoricq a écrit :

Tiens d'ailleurs c'est le vrai wc celui-là. Celui qui va pas me mettre 15 ans à me sortir le nombre de bytes  d'un fichier de 150Mo  [:petrus75]


Yay, GNU WC for the win [:kbchris]
 
Tiré directement de Textutils [:kbchris]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed