【问题标题】:File I/O in C using dynamic strings [duplicate]使用动态字符串在 C 中进行文件 I/O [重复]
【发布时间】:2014-05-21 16:48:07
【问题描述】:

我正在尝试编写一个执行以下操作的简单程序:

  • 选择文件
  • 选择如何处理文件(fopen 模式:r、w、a、r+...)
  • 写入文件

这是我目前的代码:

//Gets future file content
printf("Write content:\n");
char content[100];
fgets(content, 100, stdin);

//Selects file
printf("Select output file: ");
char file[30];
fgets(file, 30, stdin);

//Selects mode
printf("Select mode: ");
char mode[3];
fgets(mode, 3, stdin);

    FILE *fp;
    fp = fopen(file, mode);

    if (fp == 0) {
       printf("File NOT opened\n");
    }

我希望变量“file”用作文件的字符串/路径,“mode”变量也是如此。 当我运行程序时,我发现文件没有打开,这意味着 fp 是一个空指针。

PS:这不是完整的代码,但这就是破坏它的原因

提前致谢

【问题讨论】:

  • 如果文件不存在或您没有权限,那么您可能会通过我认为的 NULL 结果以外的结果收到某种类型的通知。尝试检查文件是否为 NULL?
  • 使用 w 或 w+ 模式会创建一个文件。我检查了它仍然返回相同的错误。不过还是谢谢
  • fgets() 最可能读取到file 的尾随换行符。
  • 你认为,当我将文件初始化为 char 文件 [30]。未使用的元素会保存垃圾值吗? (因为我可能不会使用 29 位)
  • 不,短字符串后未使用的元素不是问题。 fgets 写入必要的终止 NUL - fopen 将看不到之后的任何内容。问题是输入中的换行符。

标签: c string io


【解决方案1】:

添加这一行

fprintf(stderr, "file='%s'\n", file);

在您阅读 file 并了解到如果输入被按 Enter 终止时会读取换行符。

来自man fgets()(我的斜体):

fgets() 从流中最多读入一个小于 size 的字符,并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止读取。 如果读取了换行符,则将其存储到 缓冲区。一个终止的空字节('\0')存储在缓冲区中的最后一个字符之后。


根据 Chris Dodd 在下面的评论:这同样适用于读入 mode 的字符串。

【讨论】:

  • 实际上,问题在于mode 参数——包括换行符会导致fopen 失败。但是名称中的换行符可能也不需要。
  • @ChrisDodd:换行符作为文件名的后缀会使fopen 窒息,不是吗?
  • 取决于系统 -- 在类 unix 系统上,文件名中除了 / 之外的任何字符都可以。
  • 哇,这很有用。我怎样才能摆脱'\ n'?我可以遍历字符串寻找它并将其变成'\0',使用一个简单的循环和比较,但看起来可能有一个更简单的解决方案
  • @ChrisDodd:很公平。但是,我 100% 确定用户不会使用以换行符结尾的文件名。
【解决方案2】:

您需要检查文件名和模式的问题所在。 首先, fgets() 会将换行符存储到缓冲区中,这会阻止 fopen() 执行您期望的操作。 打印出您要打开的内容:

printf("opening: '%s' with mode '%s'\n", file, mode);

其次,你应该检查fopen设置的错误代码:

perror("File NOT Opened");

这样你至少会看到打开文件的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2012-07-05
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    相关资源
    最近更新 更多