【问题标题】:read() and buffer size errors in (C Linux)(C Linux) 中的 read() 和缓冲区大小错误
【发布时间】:2016-05-26 16:47:08
【问题描述】:

//编辑:我将第一个句柄的标志设置为 O_WRONLY,它应该是 O_RDONLY,这导致了问题。

我正在使用 C 语言在 Linux 中开发一个简单的程序,它将文本从一个文件复制到另一个文件。

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>

...

int main(int argc, char * argv[])
{
    int cp_from = open(argv[1],O_WRONLY);
    int cp_to = open(argv[2],O_WRONLY|O_CREAT,0777);    //make a descriptor for each file
    int size = lseek(cp_from,0,SEEK_END);               //check the size of the first file
    lseek(cp_from,0,SEEK_SET)                           //return to the start of the file, don't know if that's needed
    char *buf = (char*) malloc (size*sizeof(char));     //allocate enough memory to fit all text from 1st file into char array
    read(cp_from,buf,sizeof(buf)-1);                    //read from the 1st file to the char array
    printf("%s",buf);                                   //print the buf
    close(cp_from);
    close(cp_to);
...

所以,稍后我会将“buf”写入()到“cp_to”,这样(希望)会起作用。但是,这里只有一半的工作,因为此时它停止工作,“buf”是空的,我不知道为什么。有任何想法吗?

【问题讨论】:

  • sizeof(buf)char* 大小。
  • 请缩进您的代码。
  • 这是我在 StackOverflom 上的第一个问题,我还不习惯这里格式化^^。我把“sizeof(buf)-1”改成了“size”,还是不行。
  • lseek() 返回 off_t 而不是 int
  • “仍然不起作用”没有用。解释结果以及您的期望。

标签: c linux file buffer


【解决方案1】:

以下是一些评论点:

  1. Don't cast the return value of malloc() in C
  2. 不要在堆指针上使用sizeof,以为它会返回与分配的缓冲区大小有关的任何内容;它不会。您将获得指针的大小。
  3. 使用正确的类型,而不仅仅是int 用于所有内容。类型很重要,并非所有类型都像 int
  4. 不要将从文件中读取的随机数据视为字符串。
  5. 不要进行 I/O,也不要检查返回值。 I/O 可能会失败。
  6. ...内存分配也是如此。

最好使用一个小的(或较小的)固定大小的缓冲区,并在循环中读/写。这样,您的程序会使用有限的内存量,而不管文件的大小。

【讨论】:

  • 感谢您的提示。是的,我考虑过使用固定大小的缓冲区,但我只是想看看所有这些功能如何协同工作(我对 Linux 中的 C 编程有点陌生)。我把“sizeof(buf)-1”改成“size-1”还是不行。
  • 您还可以添加“始终使用正确的类型”。例如,lseek 返回 off_t,而不是 int,根据 pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html
【解决方案2】:

以下代码:

  1. 仍然有关于未使用变量argc 的警告(参见 cmets)
  2. 缺少用于检查从系统函数调用返回的错误指示的代码
  3. 确实有效

现在是代码

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

#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{

    int cp_from = open(argv[1], O_RDONLY);

    int cp_to = open(argv[2], O_WRONLY|O_CREAT,0777);

       //make a descriptor for each file


    size_t size = (size_t)lseek(cp_from,0,SEEK_END);               //check the size of the first file
    lseek(cp_from,0,SEEK_SET);
    //return to the start of the file, don't know if that's needed

    char *buf = malloc (size);     //allocate enough memory to fit all text from 1st file into char array
    read( cp_from, buf, size );                    //read from the 1st file to the char array
    write( cp_to, buf, size );                                   //print the buf
    close(cp_from);
    close(cp_to);
}

【讨论】:

  • 哦,返回文件指针到文件开头是绝对需要的,否则read()函数只会返回一个0,表示EOF
猜你喜欢
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 2013-09-30
  • 2011-11-26
  • 2017-04-07
  • 1970-01-01
  • 2011-10-29
相关资源
最近更新 更多