简体   繁体   English

如果参数不是文件,则从标准输入中读取

[英]If argument isn't a file, then read from stdin

I have a program that takes command line arguments, checks if they are files, if they are, then do something, if not, do something else. 我有一个使用命令行参数的程序,检查它们是否为文件,是否为文件,然后执行某些操作,如果不是,则执行其他操作。

The basic structure I have looks like this 我的基本结构如下所示

for (i=1;i<argc-1;i++){
    if ((fp=open (argv[i],"r"))==NULL){
        #Do blah blah
    }
    else{
        #do blah blah
    }
}

But for some reason, when my argument isn't a file, instead of doing blah blah, it returns an error saying that it isn't a directory or file. 但是由于某种原因,当我的论点不是文件时,它不是返回目录而是文件,而是返回错误信息。 Is there something wrong with my if statements? 我的if语句有问题吗?

The open() system call will return a negative value if there was a problem, so fp technically won't be NULL . 如果有问题, open()系统调用将返回负值,因此fp技术上讲不会为NULL

Also, as stated in @Kninnug's comment, open expects an int as its second param, so you would want O_RDONLY instead of "r" 另外,正如@Kninnug的评论中所述,open期望将int作为其第二个参数,因此您需要O_RDONLY而不是"r"

Try chaning it to 尝试改变一下

if((fp=open(argv[i], O_RDONLY))==-1)

Or, go with @Kninnug's suggestion and use fopen() . 或者,遵循@Kninnug的建议并使用fopen() If you do, you will need a FILE * pointer instead of an int . 如果这样做,则将需要FILE *指针而不是int

Your file name would be in argv[1]. 您的文件名将在argv [1]中。 So instead of for (i=1;i<argc-1;i++){ you should have for (i=1;i<argc;i++){ ` 因此,您应该拥有for (i=1;i<argc;i++){而不是for (i=1;i<argc-1;i++){

Change 更改

if ((fp=open (argv[i],"r"))==NULL)

To

if((fp=open(argv[i],"r"))==-1)

Checking if argument is a path to a file and attempting to open a file are 2 different things. 检查参数是否为文件的路径并尝试打开文件是两件事。 There are lots of reasons why fopen() fails, but the argument is a legitimate file name. fopen()失败的原因有很多,但是参数是合法的文件名。

To see if an argument is a file, use stat() . 要查看参数是否为文件,请使用stat()

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> 

int isfile(const char *path) {
  struct stat buf;
  int retval = stat(path, &buf);

  // A pedantic approach would also check the `errno`.
  if (retval) return 0;

  switch (buf.st_mode & S_IFMT) {
    case S_IFREG: return 1;
    // Maybe other cases could return 1 depending on OP's needs.
  }
  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM