首页 > 解决方案 > 在复制 wc 命令的 C 程序中使用两个缓冲区

问题描述

我有以下代码模拟来自 linux 的 wc 命令。我需要使用尺寸为 4096 的缓冲区,但由于某种原因,当我执行此代码时,我得到以下结果:

0 0 0 wcfile

即使文件不为空,我也会得到 0 行、单词和字节。我正在使用的代码如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define LUNG_BUF 4096

int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;

char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE; 
 if ( argc !=2 )
 {
     printf( "Nu ati introdu snumele  fisierului\n%s", argv[0]);
 }
 else{
     FILE *file = fopen( argv[1], "r");

   if(file == 0){
      printf("can not find :%s\n",argv[1]);
   }
   else{
            char *thefile = argv[1];

       while (read(fileno(file),buffer,LUNG_BUF) ==1 )
      {
         bytes++;
         if ( buffer[0]== ' ' || buffer[0] == '\t'  )
         {
            state = WHITESPACE;
         }
         else if (buffer[0]=='\n')
         {
            newLine++;
            state = WHITESPACE;
         }
         else 
         {
            if ( state == WHITESPACE )
            {
               words++;
            }
            state = WORD;
         }

      }        
      printf("%d %d %d %s\n",newLine,words,bytes,thefile);        
   }
 } 

}```

标签: cshellbufferwc

解决方案


read 尝试将最多 LUNG_BUF 字节读入缓冲区并返回实际读取的字节数(或在文件结束的情况下为零或 -1 表示错误)。

这意味着检查== 1将在大多数情况下失败。

如果您想解释数据,那么读取比最大缓冲区大小少一个字节也是有意义的,以便能够在缓冲区末尾放置一个终止 NUL 字节。

然后,您可以评估此​​数据,例如,通过使用在每次循环传递时设置为缓冲区开头的指针。

所以你的代码看起来像这样:

size_t n;
while ((n = read(fileno(file), buffer, LUNG_BUF - 1)) > 0) {
    buffer[n] = '\0';
    char *ptr = buffer;
    while (*ptr) {
        bytes++;
        if (*ptr == ' ' || *ptr == '\t') {
            state = WHITESPACE;
        } else if (*ptr == '\n') {
            newLine++;
            state = WHITESPACE;
        } else {
            if (state == WHITESPACE) {
                words++;
            }
            state = WORD;
        }
        ptr++;
    }
}

如果该行实际上更长,则另一种选择是使用提供一行或最多 4095 个字节的数据的 fgets(因为 fgets 附加了至少一个终止 NUL 字节)。

因此,您的循环稍作修改将如下所示:

while (fgets(buffer, sizeof(buffer), file)) {
    char *ptr = buffer;
    while (*ptr) {
    ...

推荐阅读