You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用getopt的's'选项无法输出活动文件的技术问题求助

问题排查:getopt的's'选项无输出问题

我设计了一个替代ls的-s选项,用于列出当前目录的普通文件,但编译运行后终端无任何输出。以下是完整代码及单独的s选项代码块:

原始完整代码

#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

#define DATA_SIZE 1000

void print_help(void)
{
    printf("Help\n");
    printf(">> cast -d (deletes file)\n");
    printf(">> cast -r (renames file)\n");
    printf(">> cast -c (create new file)\n");
    printf(">> cast -s (searches contents of file)\n");
    printf("________________________________________\n");
    printf("Find an error or a bug? please submit it in the issues section on github\n");
}

case 's': {
    int main(void)
    {
        DIR *directory;
        struct dirent *entry;

        directory = opendir(".");

        if (directory == NULL)
        {
            printf("Error reading directory\n");
            return 1;
        }

        while ((entry = readdir(directory)) != NULL)

            if (entry->d_type == DT_REG)
            {
                printf("file: %s\n", entry->d_name);
            }
    }
    if (closedir(directory) == -1)
    {
        printf("Error closing directory\n");
        return 1;
    }
    return 0;
          }
     }

int main(int argc, char **argv)
{
    int option_val = 0;
    int opt_delete = 0;
    int opt_help = 0;
    int opt_rename = 0;
    int opt_create = 0;
    int opt_search = 0;

    while ((option_val = getopt(argc, argv, "dhrcs")) != -1) {
        switch (option_val) {
        case 'd': {
        char filename[65]; //Hope your filename isnt bigger than this

    printf("Filename or path to file: ");
    scanf("%s", filename); // checks to see if your filename isnt bigger than specified

    if (remove(filename) != 0)
    {
      fprintf(stderr, "Errno: %d\n", errno);
      perror("Error msg");
    } else printf("%s, deleted.\n", filename);

            opt_delete = 1;
            break;

        case 'r': {
            char file[65], new[65];

            printf("File: ");
            scanf("%s", file);

            printf("New name: ");
            scanf("%s", new);

           if (rename(file, new) != 0)
         {
              fprintf(stderr, "Errno: %d\n", errno);
              perror("Error msg");
           } else printf("%s --> %s", file, new);
            opt_rename = 1;
            break;
        case 'c': {

        FILE *f = fopen("Castdocument.txt", "w+");
        
        fprintf(f, "Finished with maybe no errors? Rename this file to whatever you would like and change the filename extension with ""cast -r""");
            
        printf("File created! (Check your home directory for ""Castdocument.txt"" file and modify that to fit your needs)");

        fclose(f);

        opt_create = 1;

        case 'h': {
        print_help();
            opt_help = 1;
            break;
    default:; /* '?' */
            //print_help();
        }

      if (opt_delete) {
        printf("\n");
    } if (opt_rename) {
        printf("\n");
    }  if (opt_help)  {
         print_help();
    } if (opt_search) {
    printf("\n");
    } if (opt_create) {
        printf("\n");
           }
          }
        }
      }
    }
  }
}

单独的's'选项代码块

case 's': {
    int main(void)
    {
        DIR *directory;
        struct dirent *entry;

        directory = opendir(".");

        if (directory == NULL)
        {
            printf("Error reading directory\n");
            return 1;
        }

        while ((entry = readdir(directory)) != NULL)

            if (entry->d_type == DT_REG)
            {
                printf("file: %s\n", entry->d_name);
            }
    }
    if (closedir(directory) == -1)
    {
        printf("Error closing directory\n");
        return 1;
    }
    return 0;
          }
     }

错误原因分析

  1. case 's'定义在全局作用域,不属于任何switch语句
    你把s选项的代码块直接写在全局,没有放到main函数里的switch结构中,程序完全不会执行这部分逻辑。
  2. s选项代码嵌套了多余的int main(void)函数
    C程序只能有一个入口main函数,分支内定义的main函数根本不会被执行。
  3. 主switch语句缺少case 's'分支
    程序无法响应-s参数,即使修复前面的问题也不会触发逻辑。
  4. 部分case分支缺失break
    比如case 'c'后没有break,会导致执行完创建文件逻辑后,继续执行case 'h'的帮助打印。
  5. opt_search变量未被赋值
    主函数末尾的判断依赖该变量,但s分支没有设置它,影响后续收尾逻辑。

修复后的完整代码

#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

#define DATA_SIZE 1000

void print_help(void)
{
    printf("Help\n");
    printf(">> cast -d (deletes file)\n");
    printf(">> cast -r (renames file)\n");
    printf(">> cast -c (create new file)\n");
    printf(">> cast -s (lists regular files in current directory)\n");
    printf("________________________________________\n");
    printf("Find an error or a bug? please submit it in the issues section on github\n");
}

int main(int argc, char **argv)
{
    int option_val = 0;
    int opt_delete = 0;
    int opt_help = 0;
    int opt_rename = 0;
    int opt_create = 0;
    int opt_search = 0;

    while ((option_val = getopt(argc, argv, "dhrcs")) != -1) {
        switch (option_val) {
            case 'd': {
                char filename[65];
                printf("Filename or path to file: ");
                scanf("%s", filename);

                if (remove(filename) != 0)
                {
                    fprintf(stderr, "Errno: %d\n", errno);
                    perror("Error msg");
                } else {
                    printf("%s, deleted.\n", filename);
                }
                opt_delete = 1;
                break;
            }
            case 'r': {
                char file[65], new[65];
                printf("File: ");
                scanf("%s", file);
                printf("New name: ");
                scanf("%s", new);

                if (rename(file, new) != 0)
                {
                    fprintf(stderr, "Errno: %d\n", errno);
                    perror("Error msg");
                } else {
                    printf("%s --> %s\n", file, new);
                }
                opt_rename = 1;
                break;
            }
            case 'c': {
                FILE *f = fopen("Castdocument.txt", "w+");
                if (f == NULL) {
                    perror("Failed to create file");
                    break;
                }
                fprintf(f, "Finished with maybe no errors? Rename this file to whatever you would like and change the filename extension with \"cast -r\"");
                printf("File created! (Check current directory for \"Castdocument.txt\" file and modify that to fit your needs)\n");
                fclose(f);
                opt_create = 1;
                break;
            }
            case 'h': {
                print_help();
                opt_help = 1;
                break;
            }
            case 's': {
                DIR *directory;
                struct dirent *entry;

                directory = opendir(".");
                if (directory == NULL)
                {
                    printf("Error reading directory\n");
                    opt_search = 1;
                    break;
                }

                while ((entry = readdir(directory)) != NULL) {
                    if (entry->d_type == DT_REG)
                    {
                        printf("file: %s\n", entry->d_name);
                    }
                }

                if (closedir(directory) == -1)
                {
                    printf("Error closing directory\n");
                }
                opt_search = 1;
                break;
            }
            default:
                print_help();
                break;
        }
    }

    if (opt_delete) printf("\n");
    if (opt_rename) printf("\n");
    if (opt_search) printf("\n");
    if (opt_create) printf("\n");

    return 0;
}

关键修复说明

  • 将s选项逻辑移入main函数的switch语句,作为case 's'分支
  • 删除分支内多余的main函数定义
  • 为case 'c'补上break,避免逻辑串执行
  • 修正print_help中s选项的描述(原描述与实际功能不符)
  • 增加fopen失败的错误判断,增强程序健壮性
  • 在s分支中设置opt_search = 1,符合收尾逻辑要求
  • 为while循环添加大括号,避免缩进导致的逻辑歧义

内容的提问来源于stack exchange,提问作者Xenon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:40:40