【问题标题】:C Language Command Line Arguments + Reading in FileC 语言命令行参数 + 读取文件
【发布时间】:2017-03-18 08:54:22
【问题描述】:

我正在尝试制作一个从 ubuntu 终端获取命令并同时读取文件的程序。命令将是,如果用户键入“-c”,它将读取文件并打印字符数,如果用户键入“-w”,它将打印读取文件中的字数,“-l”打印换行符的数量人物。无论如何,我尝试使用 fscanf 来计算字符数,但由于某种原因它似乎不起作用。谁能解释我做错了什么或者是否有更好的方法来做到这一点?

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


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

int i;
char words[1000];
int counter = 0;
for(i = 0; i < argc; i++){
  if(strncmp(argv[i], "-c", 2) == 0){
     if(argv[i + 1] != NULL){
        while((fscanf(argv[i + 1], "[^\n]%s", words[i])) != EOF){
           counter++;
        }
     printf("%d characters\n", counter); 
     }
     printf("print character count\n");
  }
  else if(strncmp(argv[i], "-w", 2) == 0){
     printf("print word counts\n");
  }
  else if(strncmp(argv[i], "-l", 2) == 0){
     printf("print newline counts\n");
  }
  else if(strncmp(argv[i], "-h", 2) == 0){
     printf("prints help\n");
  }
}

}

【问题讨论】:

  • 从字符串中读取是 sscanf 而不是 fscanf
  • 你也可以使用getopt库来解析命令行参数。

标签: c linux command-line command-line-arguments


【解决方案1】:
  • fscanf 的第一个参数是打开的流,而不是文件名。您需要将文件名传递给fopen 以获取流。

  • 您尝试使用fscanf 的方式非常不安全,与gets 一样糟糕,因为它很容易溢出您的固定大小缓冲区。以缓冲区大小为参数的fgets会好很多。

  • 您的fscanf 格式字符串错误。当您传递一个字符集时,括号中的值在% 之后而不是在它之前,并且您不要另外使用s。但是当你切换到fgets 时,这个问题就会免费消失。

  • fscanf 接收值的参数需要是指针,但您传递的是单个数组元素。因为fscanf 是可变参数,所以这只是未定义的行为。 (一些编译器对scanf 格式代码有特殊处理,并会警告您类型不匹配,但没有检测可变参数类型不匹配的通用方法。

  • 读到换行符是计算行数的方法,而不是字符数。要读取单个字符,请使用 fgetc

【讨论】: