【发布时间】:2019-07-07 07:05:57
【问题描述】:
我有一个使用 gcc 和 makefile 在 macOS High Sierra 上构建的 C 程序。程序做的第一件事是读取一个二进制输入文件。文件名可以在终端命令行中与 shell 命令一起指定,也可以在未指定时由程序要求提供。
我的问题是当输入文件没有与shell命令一起指定时,程序返回错误,说它无法打开文件。
以下是有效和无效的方法: (程序和输入文件在同一目录下)
- 打开终端
- 从命令行输入:
./program_name –i input.dat
=> 工作正常
- 打开终端
- 从命令行类型:
./program_name
- 程序提示: 输入文件:
- 我输入:input.dat
=> 打开文件出错
- 打开 Finder 并转到包含程序和输入文件的目录
- 双击程序名称图标
- 程序在终端启动并提示: 输入文件:
- 我输入:input.dat
=> 打开文件出错
我在运行正常的 linux 和 windows 上运行完全相同的源代码,所以我认为它一定是我不理解的操作系统的东西?
我可以补充一点,该程序不受信任,因为它不是来自应用商店。 CTRL-点击图标解决了这个问题。
--EDIT - 很抱歉没有添加可验证的代码。
澄清:argc/argv 部分工作正常。这是例程的最后一部分,它提示输入出错的文件名。也许这确实是 Jabberwocky 建议的路径。我今晚会检查一下,并会在这里跟进。
void GetFileName(nr_args, args, filename, json)
int nr_args;
char **args;
char *filename;
int* json;
{
int i = 1;
filename[0] = '\0';
/* the command 'interpreter' itself is stored in argv[0] */
while (i<nr_args) {
if (strcmp(args[i], "-e") == 0) {
/* we cannot set the json flag here, because */
/* flags have not been initialized yet */
*json = 1;
i++;
}
else {
if (strcmp(args[i], "-i") == 0) {
if (nr_args > i+1) {
/* inputfile was specified */
strncpy(filename, args[++i], MAX_ID_LENGTH);
i++;
}
}
else {
PrintError(41, NULL, args[i]);
i++;
}
}
}
if (filename[0] == '\0') {
printf("\n\nInputfile: ");
scanf("%19s", filename);
filename[MAX_ID_LENGTH] = '\0';
/* clear the input buffer, to prevent parsing an */
/* empty string as the first user command */
/* always do a getchar() independent of OS */
getchar();
printf("\n");
}
}
这是打开文件的部分(来自 main() )
/* Get filename */
GetFileName(argc, argv, inputfile, &json);
/* Open the datafile */
if ((datafile = fopen(inputfile, "rb")) == NULL) {
PrintError(40, NULL, inputfile);
ExitProgram();
return(OK);
}
EDIT2——根据 Andrew Henle 的回复,这是原型。
void GetFileName(int, char**, char*, int*);
该函数是从定义它的同一文件中调用的。
【问题讨论】:
-
请显示解析命令行参数并根据参数打开输入文件的代码以及读取文件名输入并尝试打开文件的代码。
-
可能是因为当前目录不是你想的那样。使用
getcwd获取当前工作目录并打印出来,这可能会给出提示。请提供minimal reproducible example。另请阅读:stackoverflow.com/questions/298510/… -
你怎么打电话给
GetFileName()?您需要提供一个完整的示例,因为如果将这种古老风格的函数定义与当前的函数原型混合使用,它可能会危险。 -
@Marnix 没有通用解决方案,这可能很有趣:stackoverflow.com/q/933850/898348