1

我希望我可以提供更多信息,但我真的不知道这里发生了什么。此代码根据用户参数(默认情况下附加)打开文件以进行附加或覆盖。它会到达用户输入的 fgets,然后一旦输入输入,它就会进行段错误并转储核心。这很奇怪,因为在我实现参数之前(即它只是 ./a.out 文件)它工作得很好,所以我猜它与关于参数的新内容有关......

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

int printhelp(void);

int main(int argc, char *argv[])
{
  char input[256];
  int loopstat = 0;
  FILE *inputfile;

  if (argc < 2) /* Check argc for minimum 2 arguments (i.e. cw FILE) */
  {
    printf("ca: missing file operand\n");
    return 0;
  }
  else if (argc > 2) /* Check argc for more than 2 arguments (i.e. cw -o FILE) */
  {
    if (strncmp(argv[1], "-", 1) == 0) /* if first argument begins with "-", it must be an option, so descend into option checking */
    {
      if (strcmp(argv[1], "-a") == 0) /* If -a option is given, open for appending */
      {
        FILE *inputfile = fopen(argv[2], "a");
      }
      else if (strcmp(argv[1], "-o") == 0) /* If -o option is given, open for overwriting */
      {
        FILE *inputfile = fopen(argv[2], "w");
      }
      else if (strcmp(argv[1], "--help") == 0) /* If --help option is given, print help and quit */
      {
        printhelp();
        return 0;
      }
      else
      {
        printf("cw: invalid option\n"); /* If invalid option is given, print the fact and quit*/
        return 0;
      }
    }
  }
  else /* if argc is equal to 2 (i.e. "cw FILE" or "cw -o")...*/
  {
    if (strncmp(argv[1], "-", 1) == 0) /* Check if user has specified an option but no file (i.e. "cw -o") */
    {
      printf("cw: missing file operand\n"); /* If they have, print that no file is spec'd and quit */
      return 0;
    }
    else /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
    {
      FILE *inputfile = fopen(argv[2], "a");
    }
  }

  /* Writing loop */
  printf("Enter input...\n");
  while (loopstat == 0) /* Get user input and write to file until they give exit command */
  {
    fgets(input, 256, stdin); /* Get user input */

    if (strcmp(input, ":x\n") == 0) /* If input == exit command, quit */
    {
      printf("co: exit received, terminating...\n");
      loopstat++;
    }
    else /* Write to file */
    {
      fprintf(inputfile, "%s", input);
    }
  }
  fclose(inputfile);
}

int printhelp(void) /* Print help on --help command */
{
  printf(
      "Usage: ca FILE\nContinuously append input to the FILE\nca does not currently support multiple file appension.\nReport bugs to scamp@lavabit.com\n");
  return 0;
}

PS对不起,如果我弄乱了缩进,在这么多代码的所有内容之前必须添加四个空格真的很令人困惑。

4

4 回答 4

5

在这里,您正在隐藏您的变量:

else  /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
{
    FILE *inputfile = fopen(argv[2], "a");
}

应该

else  /* If not, it's a legit file with no other arguments (e.g. "cw FILE") so open it in append mode by default */
{
    inputfile = fopen(argv[2], "a");
}

你有几个这样的实例,所以也删除那里的声明。

于 2013-06-23T13:31:12.787 回答
2

inputfile多次声明标识符,但每次都不是同一个对象。

例如,查看该程序的行为(来自Wikipedia):

#include <stdio.h>

int main(void)
{ 
    char x = 'm';

    printf("%c\n", x);

    {
        printf("%c\n", x);
        char x = 'b';
        printf("%c\n", x);
    }

    printf("%c\n", x);
}

inputfile只需声明一次,然后在if语句中分配它。

 FILE *inputfile;

 if (/* ... */)
     inputfile = /* ... */
 else if (/* ... */)
     inputfile = /* ... */
 else
     inputfile = /* ... */
于 2013-06-23T13:31:11.380 回答
2
int main(int argc, char *argv[])
{
    char input[256];
    int loopstat = 0;
    FILE *inputfile;

那么你有:

    if (strcmp(argv[1], "-a") == 0)  
    {
        FILE *inputfile = fopen(argv[2], "a");
    }

您不应重新声明新对象inputfile,而应重用您inputfile在函数顶部声明的对象。

例子:

  inputfile = fopen(argv[2], "a");
于 2013-06-23T13:31:44.023 回答
2

问题就在那里:

FILE *inputfile;
....
if (strcmp(argv[1], "-a") == 0)             
{
    FILE *inputfile = fopen(argv[2], "a");
}

通过这种方式编写,您可以inputfile从编译器中隐藏变量。因此,开头定义的变量保持未初始化

你应该这样写:

if (strcmp(argv[1], "-a") == 0)           
{
    inputfile = fopen(argv[2], "a");
}

所以现在你将使用函数顶部定义的变量。

您应该阅读有关变量范围的信息。

于 2013-06-23T13:31:49.240 回答