这些系统调用有什么问题?

发布于 2024-09-26 20:05:28 字数 1560 浏览 7 评论 0原文

我在调试这段代码时不知所措。我从指南中复制了示例,该文件是否索引不正确?

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

char *inicio(void);

main(void)
{
  char *c;
  int fd, sz, i;    
  c = inicio();

  fd = open("input.in", O_RDONLY);
  if (fd < 0) { perror("r1"); exit(1); }

  sz = read(fd, c, 10);
  printf("We have opened input.in, and have called read(%d, c, 10).\n", fd);
  printf("read has read %d bytes.\n", sz);
  printf("The bytes are these: %s\n", c);

  i = lseek(fd, 0, SEEK_CUR);
  printf("lseek(%d, 0, SEEK_CUR) returns the current location on the file being %d\n\n", fd, i);

  printf("We now look for the start of the file and call read(%d, c, 10)\n",fd);
  lseek(fd, 0, SEEK_SET);
  sz = read(fd, c, 10);

  printf("The reading returns the following bytes: %s\n", c);

  printf("We now execute lseek(%d, -6, SEEK_END). and return %d\n",fd, (int) lseek(fd, -6, SEEK_END));
  printf("Executing read(%d, c, 10), we get the following bytes: ", fd);

  sz = read(fd, c, 10);

  printf("Finally, we execute lseek(%d, -1, SEEK_SET).  This returns -1.\n", fd);
  printf("perror() indicates the fault:\n");
  fflush(stdout);

  i = lseek(fd, -1, SEEK_SET);
  perror("l1");
}

char *inicio(void)
{
  char *bytes;
  int j;
  bytes = (char *) calloc(100, sizeof(char));
  for(j=0;j<100;j++){bytes[j]=rand()%32+1;}
  return bytes;
}

输入文件是:

 Jim Plank
 Claxton 221

I'm at a loss debugging this code. I copied the example from a guide, is this file being improperly indexed?

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

char *inicio(void);

main(void)
{
  char *c;
  int fd, sz, i;    
  c = inicio();

  fd = open("input.in", O_RDONLY);
  if (fd < 0) { perror("r1"); exit(1); }

  sz = read(fd, c, 10);
  printf("We have opened input.in, and have called read(%d, c, 10).\n", fd);
  printf("read has read %d bytes.\n", sz);
  printf("The bytes are these: %s\n", c);

  i = lseek(fd, 0, SEEK_CUR);
  printf("lseek(%d, 0, SEEK_CUR) returns the current location on the file being %d\n\n", fd, i);

  printf("We now look for the start of the file and call read(%d, c, 10)\n",fd);
  lseek(fd, 0, SEEK_SET);
  sz = read(fd, c, 10);

  printf("The reading returns the following bytes: %s\n", c);

  printf("We now execute lseek(%d, -6, SEEK_END). and return %d\n",fd, (int) lseek(fd, -6, SEEK_END));
  printf("Executing read(%d, c, 10), we get the following bytes: ", fd);

  sz = read(fd, c, 10);

  printf("Finally, we execute lseek(%d, -1, SEEK_SET).  This returns -1.\n", fd);
  printf("perror() indicates the fault:\n");
  fflush(stdout);

  i = lseek(fd, -1, SEEK_SET);
  perror("l1");
}

char *inicio(void)
{
  char *bytes;
  int j;
  bytes = (char *) calloc(100, sizeof(char));
  for(j=0;j<100;j++){bytes[j]=rand()%32+1;}
  return bytes;
}

the input file is:

 Jim Plank
 Claxton 221

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

╭ゆ眷念 2024-10-03 20:05:28

如果您寻求距文件开头的负偏移量,则会收到错误 - 文件开头之前没有可访问的字节。

另外,您应该始终检查或捕获系统调用的结果,而不是依赖于设置的 errno 。 C 库从不将 errno 设置为零(进程/线程启动时除外)。即使函数成功,它也可以设置为非零值。在 Solaris 上,在写入文件后设置 errno 是例行公事,因为该文件不是终端,并且库尝试的操作只能在终端上成功。


工作代码,减去通过“malloc()”分配的内存。它显式地仅打印读取的字符数('<<%.*s>>' 将长度限制为给定的大小;尖括号可以轻松查看所读取的数据正在打印)。

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

int main(void)
{
    char c[100];
    int fd, sz, i;

    fd = open("input.in", O_RDONLY);
    if (fd < 0)
    {
         perror("Error from open(\"input.in\", O_RDONLY)");
         exit(1);
     }

    sz = read(fd, c, 10);
    printf("Opened input.in (fd = %d)\n", fd);
    printf("We called read(fd, c, 10) and read %d bytes: <<%.*s>>\n",
           sz, sz, c);

    i = lseek(fd, 0, SEEK_CUR);
    printf("lseek(fd, 0, SEEK_CUR) returns the current offset of %d\n", i);

    printf("We seek to start of the file and call read(fd, c, 10)\n");
    i = lseek(fd, 0, SEEK_SET);
    if (i != 0)
        perror("Error from lseek(fd, 0, SEEK_SET)\n");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("We read the following bytes: <<%.*s>>\n", sz, c);

    printf("We now execute lseek(fd, -6, SEEK_END) which returns %d\n", 
           (int) lseek(fd, -6, SEEK_END));
    printf("Executing read(fd, c, 10), we get the following bytes: ");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("<<%.*s>>\n", sz, c);

    printf("Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1\n");
    fflush(stdout);

    if ((i = lseek(fd, -1, SEEK_SET)) < 0)
        perror("Error from lseek(fd, -1, SEEK_SET)");
    printf("i = %d\n", i);
    return 0;
}

输出:

Opened input.in (fd = 3)
We called read(fd, c, 10) and read 10 bytes: <<Jim Plank
>>
lseek(fd, 0, SEEK_CUR) returns the current offset of 10
We seek to start of the file and call read(fd, c, 10)
We read the following bytes: <<Jim Plank
>>
We now execute lseek(fd, -6, SEEK_END) which returns 16
Executing read(fd, c, 10), we get the following bytes: <<n 221
>>
Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1
Error from lseek(fd, -1, SEEK_SET): Invalid argument
i = -1

If you seek to a negative offset from the start of the file, you get an error - there are no accessible bytes before the beginning of the file.

Also, you should always check or capture the results of system calls, rather than relying on errno being set. The C library never sets errno to zero (other than when the process/thread starts). It can be set to a non-zero value even if the function succeeded. On Solaris, it is routine for errno to be set after writing to a file because the file is not a terminal and the library attempts an operation that only succeeds on a terminal.


Working code, minus memory allocation via 'malloc()'. It explicitly prints only the number of characters read ('<<%.*s>>' limits the length to the size given; the angle brackets make it easy to see the data that is being printed).

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

int main(void)
{
    char c[100];
    int fd, sz, i;

    fd = open("input.in", O_RDONLY);
    if (fd < 0)
    {
         perror("Error from open(\"input.in\", O_RDONLY)");
         exit(1);
     }

    sz = read(fd, c, 10);
    printf("Opened input.in (fd = %d)\n", fd);
    printf("We called read(fd, c, 10) and read %d bytes: <<%.*s>>\n",
           sz, sz, c);

    i = lseek(fd, 0, SEEK_CUR);
    printf("lseek(fd, 0, SEEK_CUR) returns the current offset of %d\n", i);

    printf("We seek to start of the file and call read(fd, c, 10)\n");
    i = lseek(fd, 0, SEEK_SET);
    if (i != 0)
        perror("Error from lseek(fd, 0, SEEK_SET)\n");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("We read the following bytes: <<%.*s>>\n", sz, c);

    printf("We now execute lseek(fd, -6, SEEK_END) which returns %d\n", 
           (int) lseek(fd, -6, SEEK_END));
    printf("Executing read(fd, c, 10), we get the following bytes: ");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("<<%.*s>>\n", sz, c);

    printf("Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1\n");
    fflush(stdout);

    if ((i = lseek(fd, -1, SEEK_SET)) < 0)
        perror("Error from lseek(fd, -1, SEEK_SET)");
    printf("i = %d\n", i);
    return 0;
}

Output:

Opened input.in (fd = 3)
We called read(fd, c, 10) and read 10 bytes: <<Jim Plank
>>
lseek(fd, 0, SEEK_CUR) returns the current offset of 10
We seek to start of the file and call read(fd, c, 10)
We read the following bytes: <<Jim Plank
>>
We now execute lseek(fd, -6, SEEK_END) which returns 16
Executing read(fd, c, 10), we get the following bytes: <<n 221
>>
Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1
Error from lseek(fd, -1, SEEK_SET): Invalid argument
i = -1
葬花如无物 2024-10-03 20:05:28

printf("字节如下:%s\n", c);

访问冲突(保证一个)。您没有 '\0' 终止符。

同样适用于:

printf("读取返回以下字节:%s\n", c);

printf("The bytes are these: %s\n", c);

Access violation (guaranteed one). You don't have a '\0' terminator.

Same goes for:

printf("The reading returns the following bytes: %s\n", c);

鸵鸟症 2024-10-03 20:05:28

您到底期望文件​​的第 -1 位置是什么?也许您想要 SEEK_CUR 或 SEEK_END 而不是 SEEK_SET。

What exactly do you expect at the -1th position of the file? Maybe you wanted SEEK_CUR or SEEK_END instead of SEEK_SET.

泅人 2024-10-03 20:05:28
c[sz] = '\0';

在 read 调用之后。

c[sz] = '\0';

after the read calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文