无法弄清楚为什么我的字符数、单词数和行数适用于文件输入,但不适用于标准输入

Cant figure out why my character, word and line count will work with file input but not from stdin

我是 C 编程的新手,我在使用 stdin 时遇到了问题。我的代码应该显示输入文件或标准输入中包含的字数、行数和字符数。如果它显示文件中的数字,那么文件名需要与单词、行和字符数一起显示,如下所示:

0 0 0 test.txt

我能够做到这一点,但标准输入将无法工作,我得到 "Segmentation Fault (core dumped)"

enum state
{
  START,
  WORD,
  DELIM,
};

FILE *
input_from_args(int argc, const char *argv[])
{
  if (argc == 1){
    return stdin;
  } else {
    return fopen(argv[1], "r");
  }
}

void
wcount(FILE *src, FILE *dest, const char *argv[])
{
  int ch, wc, lc, cc;
  enum state cstate;

  wc = lc = cc = 0;
  cstate = START;
  while ((ch = fgetc(src)) != EOF){
    cc++;
    switch (cstate){
    case START:
      if (isspace(ch)){
 cstate = DELIM;
 if (ch == '\n'){
   lc++;
 }
      } else{
 cstate = WORD;
 wc++;
      }
      break;
    case DELIM:
      if (ch == '\n'){
 lc++;
      } else if (!isspace(ch)){
 cstate = WORD;
 wc++;
      }
      break;
    case WORD:
      if (isspace(ch)){
 cstate = DELIM;
 if (ch == '\n'){
   lc++;
 }
      }
      break;
    }
  }
  fprintf(dest, "%d\t%d\t%d\t%s\n", wc, lc, cc, argv[1]);
}

我觉得我 运行 解决这个问题的原因与我的 wcount 函数中的 argv[] 有关。

抱歉,这个 post 中的文字墙,我是这个网站的新手,不完全知道我应该如何 post 提问。谢谢

编辑:文件是我编译后指定的运行程序

所以我说

./tstats test.txt

并显示

0    0    0    test.txt

void wcount(FILE *src, FILE *dest, const char *argv[]) 

你得到参数 argv 只是为了在

处使用它
fprintf(dest, "%d\t%d\t%d\t%s\n", wc, lc, cc, argv[1]);

但是你使用它时没有检查它是否真的存在,你确实input_from_args函数中做了一些事情。

所以您也可以将 argc 作为 wcount 的参数传递并执行:

if (argc == 1) {
    fprintf(dest, "%d\t%d\t%d\tstdin\n", wc, lc, cc); // no argv[1]
else {
    fprintf(dest, "%d\t%d\t%d\t%s\n", wc, lc, cc, argv[1]);
}

或者您传递一个 char* filename 参数而不是 argv,您在 wcount 的调用之外检查该参数,然后继续

fprintf(dest, "%d\t%d\t%d\t%s\n", wc, lc, cc, filename);

呼唤。