首页 > 解决方案 > C 系统调用 open()

问题描述

我遇到了麻烦open()。它总是返回-1,我不知道代码有什么问题。它一直在说:

r1: No such file or directory

但是txt文件与C程序在同一目录下。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define BUFFSIZE 256

char upper(char c);

int main(void){

    int fd1, read1, fd2, write2;
    char *buffer[BUFFSIZE];

    fd1 = open("minuscole.txt", O_RDONLY);
    if (fd1 < 0) { perror("r1"); exit(1); }
    read1 = read(fd1, buffer, BUFFSIZE);
    close(fd1);

    printf("%d", read1);
    if(fd2 = open("maiuscole.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644) > 0){
        write2 = write(fd2, buffer, BUFFSIZE);
    }
    close(fd2);

    return 0;
}

我希望它创建一个名为: 的文件"maiuscole.txt"并写入: 中的内容"minuscole.txt"

标签: clinuxsystem-calls

解决方案


尽管您说您的输入文件与源文件位于同一位置,但这并不意味着您也在同一位置运行可执行文件。错误消息清楚地表明您不是。

要修复,请确定您从哪个目录运行可执行文件,确保您的输入文件位于该目录中,并且您有权在该目录中创建输出文件。

如评论中所述,您的赋值语句fd2不正确,因为赋值运算符的优先级低于比较运算符。为了一致性起见,我建议您更改代码以匹配用于fd1. 请注意,这0也是一个有效的文件描述符。

fd2 = open("maiuscole.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if(fd2 >= 0){
    //...

第二个参数分别为readwrite采用void */ const void *,因此它掩盖了您将 a char *[](衰减为 a char **)传递给这些函数的错误。这不是你的意图,因为 achar **只能存储sizeof(char *)字节。您打算存储最多BUFFERSIZE字节。更改buffer为数组char而不是数组char *

char buffer[BUFFSIZE];

从输入文件中读取数据后,read调用的返回值是读取了多少字节。您应该只将那么多字节写入输出文件,而不是整个缓冲区。

    write2 = write(fd2, buffer, read1);

如果只读取了 10 个字节,则缓冲区中前 10 个字节之后的字节未初始化,您不应将它们写入输出。

还有其他情况和错误检查供您考虑。我不会提供所有解决方案,但您应该考虑到:

  • 您的输入文件可能大于BUFFSIZE.
  • 即使文件大于 ,对 的调用也read可能返回小于。BUFFSIZEBUFFSIZE
  • 调用write可能返回小于read1.

最后,关于close. 忽略 的返回值的并不孤单,close即使在生产代码中也是很常见的事情。但是,检查是否close成功仍然是一个好习惯。在某些情况下,它可能会失败,因为描述符之前已经关闭。您可能想知道是否会发生这种情况,因为它表明程序中存在某种逻辑错误。虽然关闭无效的文件描述符是良性的,但在未来,您可能会意外关闭程序的其他部分正在使用的文件描述符。


推荐阅读