1

这里的任务是:这是一个基本的 C 程序,它必须包含两个进程。第一个在文件中写入 60 个随机数。需要写入的秒数必须读取文件并仅将偶数写入另一个新文件。所以我有这段代码,需要将偶数写入文件的父进程无法正常工作。我的问题是关于代码的结构。这是描述进程的最佳方式吗?

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

int main() {
    int pid, fd, buf, i, fd2, buf2;
    pid = fork();

    switch (pid) {
    case 0: {
        printf("\n Child process is writing numbers. \n");
        fd = open("file.dat", O_RDWR | O_CREAT, 0644);

        for (i = 0; i < 60; i++) {
            buf = rand() % 20 - 10;
            printf("\n Writing number %d %d ", i + 1, buf);
            write(fd, &buf, sizeof(buf));
        }

        close(fd);
        break;
    }

    case -1: {
        printf("\n Fork error! \n");
    }

    default: {
        wait(pid);
        printf("\n Parent process is Copying numbers. \n");
        fd = open("file.dat", O_RDONLY);
        fd2 = open("file_output.dat", O_RDWR | O_CREAT, 0644);

        while (read(fd, &buf, sizeof(buf)) == sizeof(buf)) {
            if (buf & ~1)
                (buf2 = buf);
            write(fd2, &buf2, sizeof(buf2));
            printf("Writing number in file_output.dat %d \n", buf2);
        }

        close(fd2);
        close(fd);
    }
    }
    return 0;
}
4

4 回答 4

1

你的条件不对:

    if (buf &~ 1) (buf2=buf);
    write(fd2, &buf2, sizeof(buf2));

无论如何,您都写出数字,但如果它是奇数(除了您需要修复偶数/奇数测试),那么您不会更新buf2. 如果第一个数字是奇数,buf2则未初始化。

你需要这个:

    if (buf % 2 != 0) continue;
    write(fd2, &buf, sizeof(buf));
    printf("Writing number in file_output.dat %d \n", buf);

请注意,这可能无法正确测试负偶数。你可以测试一下abs(buf) % 2 != 0。唯一可能无法处理的数字是INT_MIN.

于 2013-01-29T22:25:25.393 回答
0

您对偶数的测试是错误的。您排除第 1 位,因此将选择任何大于 1 的数字。你有效地测试

if (buf & 0xfffffffe) ...

但是,您应该改为测试

if (!(buf & 1)) ...

甚至

if ((buf % 2) == 0) ...
于 2013-01-29T22:17:26.913 回答
0

好吧,代码中有几个错误。

看起来你想要实现这个:孩子写随机数,父母等待孩子终止,读取随机数,只将偶数写入第二个文件。

但是,您使用了 wait(),这是错误的函数。而是像这样使用 waitpid() :

waitpid(pid, NULL, 0);

另一个错误是在您的代码中只写入偶数。我会这样写:

if (!(buf & 1))
    write(fd2, &buf1, sizeof(buf1));

这样,您根本不需要 buf2。事实上,在你当前的代码中,如果数字不是偶数,它仍然会向文件中写入一个数字!它只会写入它再次读取的最后一个偶数。

于 2013-01-29T22:22:42.807 回答
0

当您可以使用便携式 fopen/fread/fwrite 时,为什么还要使用非便携式 open/read/write?这对我来说毫无意义。

让我们假设您的 sizeof int == 4。假设您的第一个进程写入 4 个字节,无论出于何种原因,您的第二个进程将其读取为两个 2 个字节的块,因此 read 在您的循环中返回 2:while (read(fd, &buf, sizeof(buf)) == sizeof(buf))Is 2 == sizeof (buf) ? 不。也许你的循环在错误的条件下终止......

fread 用两个参数解决了这个问题:一个是项目的大小,一个是你想要的项目数。for (size_t x = fread(&buf, sizeof buf, 1, file_ptr); x > 0; x = fread(&buf, sizeof buf, 1, file_ptr)) { /* ... */ }...“成功完成后, fread() 应返回成功读取的元素数,仅在遇到读取错误或文件结尾时才小于 nitems。” 此保证不存在用于读取。您可能需要使用 x 来确定要写入的项目数,因为这会告诉您读取了多少项目。

于 2013-01-30T01:02:07.733 回答