试图计算C中的字符,单词和行

时间:2013-11-26 03:39:57

标签: c

所以赋值是在C中模拟unix命令wc。我已经把大部分结构都关闭了,但是实际的计数部分我遇到了一些问题。

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[]){

int file;
int newLine=0, newWord=0, newChar=0, i=0;
char *string;
char buf[101];

file = open(argv[1], O_RDONLY, 0644);

int charRead=read(file, buf, 101);

if (file == -1){
    printf("file does not exist");
}
else{
    for (i; i<100; i++){
        if (buf[i]!='\0'){
            newChar++;
        }
        if (buf[i]==' '){
            newWord++;

        }
        if (buf[i]=='\n'){
            newLine++;
        }

    }
}
printf("%d\n",newWord);
printf("%d\n",newLine);
printf("%d\n",newChar);
printf("%s",argv[1]);
close(file);

}

因此,线路计数器运行良好。

除非单词末尾有空格,否则单词计数总是短暂的。我试图通过制作特例来改善这一点:

if(buf[i]!='\0' || (buf[i]=='\0' && buf[i]!=' '))

但这似乎也不起作用。

另一个问题是字符数总是偏离。我认为这与缓冲区大小有关,但我似乎找不到很多关于如何在这种情况下使缓冲区工作的文档。

请指教。谢谢!

1 个答案:

答案 0 :(得分:0)

编辑我查看了“重复”问题中给出的答案,我认为他们并没有真正解决您的问题。我编写了一个简短的程序,它可以完成您想要的任务(并且“安全”,因为它可以处理任何大小的输入)。我在一个短文件中测试了它,它给wc提供了相同的结果。

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
// count characters, words, lines
int cCount = 0, wCount = 0, lCount = 0, length;
char buf[1000];
FILE *fp;

if (argc < 2) {
  printf("usage: wordCount fileName\n");
  return -1;
}

if((fp = fopen(argv[1], "r")) == NULL) {
  printf("unable to open %s\n", argv[1]);
  return -1;
}

while(fgets(buf, 1000, fp)!=NULL) {
  int ii, isWord, isWhite;
  lCount++;
  isWord = 0;
  length = strlen(buf);
  cCount += length;
  for(ii = 0; ii<length; ii++) {
    isWhite = (buf[ii]!=' ' && buf[ii]!= '\n' && buf[ii] != '\t') ? 1 : 0;
    if (isWhite == 1) {
      if(isWord != 1) wCount++;
      isWord = 1;
    }
    if(isWhite == 0 && isWord == 1) {
      isWord = 0;
    }
  }
}
printf("Characters: %d\nWords: %d\nLines: %d\n\n", cCount, wCount, lCount);
return 0;
}

注意 - 如果您的行中包含超过1000个字符,则上述行可能会产生错误结果;这可以通过使用getline()来解决,这是一个非常安全(但非标准)的函数,它将负责为读入的行分配足够的内存。我认为你不必在此担心它。 如果你担心它,你可以使用与上面相同的技巧(你有“isWord”状态)并将其扩展到isLine(遇到\n时重置)。然后你不需要内部for循环。它的内存效率略高,但速度较慢。