6

这是家庭作业的一部分。好吧,我无法让我的作业中的东西正常工作,所以我拿出一个片段并开始玩弄它以找出问题所在。

在 C 语言的 linux 上,我试图打开/创建一个文本文件,向其中写入内容,关闭它,以读/写和附加模式打开它,然后将任何内容附加到它的末尾(在本例中,字符串“,伙计”)。但是,没有附加任何内容,但是 write 方法也没有引发错误。我不确定发生了什么。

这是代码:

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

#define BUFFSIZE 4096

int main(){
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

    int fd = open("tempfile.txt", O_RDWR | O_CREAT, mode);

    char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'};

    size_t n = sizeof(buf);
    if(write (fd, buf, n) < 0){
        printf("Error in write\n");
        printf("%s", strerror(errno));
        return 1;
    }

    close(fd);

    int fd2 = open("tempfile.txt", O_RDWR | O_APPEND);

    printf("appending dude:\n");
    char buf2[6] = {',', ' ', 'd', 'u', 'd', 'e'};
    size_t p = sizeof(buf2);
    if(write (fd2, buf2, p) < 0){
        printf("Error in write\n");
        printf("%s", strerror(errno));
        return 1;
    }

    char buf3[BUFFSIZE];
    lseek(fd2, 0, SEEK_SET);
    if(read (fd2, buf3, BUFFSIZE) < 0){
        printf("Error in read\n");
        printf("%s", strerror(errno));
        return 2;
    }
    int i;
    for (i = 0; i < strlen(buf3); ++i){
        printf("%c", buf3[i]);
    }
    printf("\n");

    close(fd2);

    return 0;
}

我试图通过弄乱一些不同的组合,将模式变量更改为 S_IRWXU | 来消除严格意义上的权限问题的可能性。S_IRWXG | S_IRWXO,在我的第二个 open 语句中将模式作为第三个参数传递,仅在第二个 open 语句中以附加模式打开文件,在第二个 open 语句中将附加模式作为第三个参数传递,等等。

我能做的最好的就是在没有 APPEND 模式的情况下在 RDWR 中打开它,然后直接覆盖现有文本......但这不是我想要的。请注意,我知道 lseek 之类的东西,但这里的目的是严格使用附加模式将文本添加到文件末尾。我不想寻求。

看看这个有什么线索吗?我敢肯定有一些明显的东西我就是不明白。

非常感谢。

4

4 回答 4

4

好吧,我刚刚尝试了您的程序,并且知道出了什么问题。

基本上,它确实有效,但有一个小故障。当您第一次将“thy fall”写入文件时,您使用一个字节char数组4096,并将整个数组写入文件。这意味着你正在写“你的堕落”,然后4088是随机的字符。稍后,当您追加时,您将追加到第 4097 个位置。这可能不是你打算做的。

如果您只是cat创建的文件,您将看到预期的输出“你的摔倒,伙计”。但是,当您完全在代码中阅读它时,您只是在阅读4096字符。因此,", dude" 部分永远不会被读取,这就是您的程序从不输出它的原因。

我的解决方案,您需要更改数组大小。并且在阅读时,以 100 或 1000 为一组读取,直到您点击 EOF(read将返回 -1)。

于 2013-10-03T05:10:26.650 回答
3

您尝试写入的字节数不正确,

char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'};
size_t n = sizeof(buf);
if(write (fd, buf, n) < 0){

而不是你应该做的

char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l', '\0'};
size_t n = strlen(buf); //use strlen 
if(write (fd, buf, n) < 0){

同样,对其他写入和读取也执行此操作。如果您没有'\0'在文件中写入终止字符串,则从文件中读取数据时将不会得到它。

在阅读时,您应该尝试直到读取整个文件,即。你明白了EOF

于 2013-10-03T05:15:56.380 回答
2

只是有个小错误,你需要把sizeof函数改成 ,strlen因为sizeof函数会返回数组的大小,而strlen函数只是返回数组中存储的字符串的长度!

于 2013-10-03T06:01:14.683 回答
-1

这是更正的代码,您还需要 O_CREAT 标志来初始创建文件

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

main()
{

int fd = open("tempfile.txt",O_CREAT|O_RDWR|O_APPEND);
        printf( "hello\n" );
        char buf[] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l', '\0'};

    size_t n = strlen(buf);

    if(!write(fd, buf, n)){
        printf("Error in write\n");
        printf("%s", strerror(errno));
        return 1;
    }

    close(fd);

    int fd2 = open("tempfile.txt", O_RDWR | O_APPEND);

    printf("appending dude:\n");
    char buf2[] = {',', ' ', 'd', 'u', 'd', 'e', '\0'};
    size_t p = sizeof(buf2);
    if(!write(fd2, buf2, p)){
        printf("Error in write\n");
        printf("%s", strerror(errno));
        return 1;
    }

    char buf3[n + p];
    lseek(fd2, 0, SEEK_SET);
    if(!read (fd2, buf3, (n + p) )){
        printf("Error in read\n");
        printf("%s", strerror(errno));
        return 2;
    }
    int i;
    for (i = 0; i < ( n + p ); ++i){
        printf("%c", buf3[i]);
    }
    printf("\n");
}
于 2016-06-04T20:34:08.970 回答