【问题标题】:Input either from stdin or file , C从标准输入或文件输入,C
【发布时间】:2017-03-04 03:27:45
【问题描述】:

我有一个程序可以从文件或键盘读取输入。我找到了一种方法来决定是从文件还是从键盘插入输入。

我需要用一种简单的方法来实现这个决定,因为我不想为每种类型的输入复制我的代码 2 次。

我尝试了类似下面的代码,但仅适用于输入文件 (arv == 1),而它从标准输入获得分段错误。

arg == 0 调试后出错

(_IO_fgets (buf=0xbffffaac "\030\031\023", n=100, fp=0x0) at iofgets.c:52)

代码:

FILE *fp;

if (arg = 1)
    fp = fopen (operationfile, "r");
else
    fp = stdin;

while (fgets(buffer, sizeof(buffer), fp) != NULL)

有没有快速的方法来做到这一点?

【问题讨论】:

  • 当你的函数调用有可能失败时,总是检查它们的返回值。 fopen() 等 I/O 功能特别容易出现故障;很少有不适合检查它们的返回值的情况。在这种情况下,您可能在错误情况下检测到您无法打开文件,而不是得到一个神秘的段错误。
  • 您最好编写代码,以便对标准输入和命名文件使用相同的代码。将读取代码放入传递文件流的函数中通常是合适的(可能还有文件名,以防它需要生成错误消息)。这使您可以更轻松地概括您的代码。
  • 当有命令行参数时 main() 的签名是:int main( int argc, char *argv[] ) 在 C 中,argc 参数永远不会小于 1。因为argv[0] 是一个指向字符的指针包含path/name 的字符串,用于程序可执行文件。要拥有单个命令行参数,argc 的值将为 2,并且该参数将在 argv[1] 处作为指向 char 字符串的指针提供。
  • 这一行:if (arg = 1) 是编译器无法捕获的常见按键错误。但是,如果文字在左侧,如if ( 1 = arg),那么编译器会捕捉到它,并且调试会容易得多。

标签: c file input stdin


【解决方案1】:
if(arg == 1) /* == */
{
    ....

应该可以解决您的大部分麻烦。 arg = 1arg 设置为 1 并始终成功,因此永远不会使用 fp=stdin; 分支。

另外,您的问题没有显示arg 的分配方式。是main()的第一个参数吗?如果是这样,那通常称为argc。如果您使用常规名称,其他开发人员将更容易理解您的代码。

编辑

  • 正如@MayurK 指出的那样,使用1 == arg 而不是arg == 1 将有助于编译器保护您免受这种情况的影响。

  • 正如@EdHeal 指出的那样,一些编译器可以选择检查if(arg=1),因为它很少是你想要的。在 GCC 中,-Wint-in-bool-context-Wparentheses 很有用(或者,更好的是,只需启动 -Wall!)。

【讨论】:

  • 也许提到一些编译器可以选择检测这样的错误
  • 在 LHS 上写常量总是一个好习惯,即如果(1 == 参数){}。如果你写“=”而不是“==”,编译器会抛出错误。
  • 好吧 gcc 没有检测到它。你是对的 。不要担心 arg ,它们是主要论点。问题解决了谢谢!
  • @MayurK:我认为尤达条件是可恶的。我不推荐他们。大多数编译器可能会在条件上下文中被引发关于赋值的警告——如果你不使用这样的编译器,是时候升级了;如果您不经常使用该级别的警告,那么您应该这样做;如果你忽略编译器警告,你不应该这样做。
  • @EugG:如果 GCC 没有给你警告,那么你实际上是在滥用 GCC。如果您使用-Wall 标志,您会收到警告,这是最低级别。当在没有启用警告的选项的情况下调用时,GCC 接受许多现代标准可疑的代码——在 GCC 5.x 之前它更成为一个问题,后来默认为 C11,因为 C89 标准既非常成功又非常松懈(必要的)。我很少在 SO 上发布无法使用 gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition 编译的代码。
猜你喜欢
  • 2011-03-30
  • 2012-11-05
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2012-04-25
  • 1970-01-01
相关资源
最近更新 更多