【问题标题】:C system calls — keep getting error with lseek and readC 系统调用 — lseek 和 read 不断出错
【发布时间】:2015-03-22 04:51:28
【问题描述】:

这是我正在为课堂练习的练习,我不明白为什么它不会运行......

我在尝试分配长度来自变量 (num2) 的 char 数组(缓冲区)时遇到问题。

你可以像这样执行文件:

./file.c offset numOfChars filename.txt

./file.c 4 10 somefile.txt

如果某个文件包含文本:

为什么这个 c 程序不工作。我想不通

程序应该打印

这不是

代码如下:

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

main(int ac, char *av[]){
    // Save the command line variables
    int num1 = av[1];
    int num2 = av[2];

    long numbyte1 = av[1];
    long numbyte2 = av[2];

    int fd = open(av[3], O_RDONLY);

    // Try to open the file
    if( fd < 0 )
        perror(fd + " - Could not open file!");

    // use stat to get file size
    struct stat sb;
    if(fstat(fd,&sb) < 0)    
        return 1;

    // Check to see if the file is big enough for the provided offset
    if(sb.st_size < num1+num2){
        perror(fd + " - Size of file is not large enough for provided offset!" + fd);
    }

    char buffer[num2];

    if(lseek(fd, numbyte1 ,SEEK_SET) < 0) return 1;

    if(read(fd, buffer, numbyte2) != numbyte2) return 1;

    printf("%s\n", buffer);

    return 0;
}

【问题讨论】:

  • (1) 注意你的编译器警告。 (2) 确保您的编译器向您发出警告(您可能正在使用gcc,所以-Wall 是最低限度;我使用-Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes -std=c11)。 (3) 如果遇到问题,请打印数据——对于lseek(),也打印您要查找的偏移量。我知道您认为您知道该值,但您不知道该值,并且打印该值会告诉您您的偏移量完全错误。如有疑问,请让程序告诉您它在做什么。这是一项关键但基本的调试技术。

标签: c unix system


【解决方案1】:

我看到的问题:

  1. ./file.c 不是运行程序的正确方法。您需要编译程序并创建可执行文件。然后,你就可以运行它了。

    如果您有gcc,请使用:

    gcc -o file -Wall file.c
    ./file 4 10 somefile.txt
    
  2. 这几行

    int num1 = av[1];
    int num2 = av[2];
    

    不对。编译器应该报告警告。使用gcc,我收到这两行的以下警告:

    soc.c:在函数“main”中: soc.c:4:15: 警告:初始化从没有强制转换的指针生成整数 [默认启用] int num1 = av[1]; ^ soc.c:5:15: 警告:初始化从没有强制转换的指针生成整数 [默认启用] int num2 = av[2];

    av[1]av[2] 的类型为 char*。如果包含整数,您可以使用标准库中的几个函数之一从中提取整数。例如

    int num1 = atoi(av[1]);
    int num2 = atoi(av[2]);
    
  3. 线条

    long numbyte1 = av[1];
    long numbyte2 = av[2];
    

    遇到同样的问题。您可以使用已经提取的数字来初始化numbypte1numbypte2

    long numbyte1 = num1;
    long numbyte2 = num2;
    
  4. 你有

    char buffer[num2];
    

    这不足以容纳具有num2 字符的字符串。您需要数组中的另一个元素来保存终止的空字符。使用:

    char buffer[num2+1];
    
  5. 从文件中读取数据后,在buffer 中添加一个终止空字符。

    if(read(fd, buffer, numbyte2) != numbyte2) return 1;
    buffer[num2] = '\0';
    

【讨论】:

  • 感谢您的帮助,但我知道,我认为它已提供。代码有问题。
  • @KevinZaki:不要做诸如“我认为它已经给出[你知道你将file.c 中的代码编译成一个程序]”之类的事情。在这里,什么都不能假设。初学者犯了最奇怪的错误,我们必须相信人们的话。要明确和准确,不要暴露自己粗心。 (请注意,file 通常是系统上的一个程序;最好不要使用该名称调用您自己的程序,而test 是另一个不应使用的名称。OTOH,program 不会被抢占 - 但是command 是。)
  • 太棒了@Jonathan Leffler!说得好,而且是真的。
猜你喜欢
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2017-08-28
  • 2021-04-20
  • 1970-01-01
  • 2019-05-17
  • 2021-06-21
  • 2020-11-11
相关资源
最近更新 更多