lseek()返回0后跟新的open()

时间:2010-01-10 19:15:50

标签: c file posix

我有以下代码(它是“示例”代码,所以没什么特别的):

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

int main()
{
    char buffer[9];
    int fp = open("test.txt", O_RDONLY);

    if (fp != -1) // If file opened successfully
    {
        off_t offset = lseek(fp, 2, SEEK_SET); // Seek from start of file
        ssize_t count = read(fp, buffer, strlen(buffer));
        if (count > 0) // No errors (-1) and at least one byte (not 0) was read
        {
            printf("Read test.txt %d characters from start: %s\n", offset, buffer);
        }

        close(fp);
    }

    int fp2 = open("test.txt", O_WRONLY);
    if (fp2 != -1)
    {
        off_t offset = lseek(fp2, 2, SEEK_CUR); // Seek fraom current position (0) - same result as above in this case
        ssize_t count = write(fp2, buffer, strlen(buffer));
        if (count == strlen(buffer)) // We successfully wrote all the bytes
        {
             printf("Wrote to test.txt %d characters from current (0): %s\n", offset, buffer);
        }

        close(fp2);
    }
}

此代码不会按原样返回第一个打印输出(读取),第二个打印输出显示:“从当前(0)写入test.txt 0个字符:”表示它没有在文件中的任何位置搜索缓冲区是空的。

奇怪的是,如果我从fp2 = open("test.txt", O_WRONLY);注释掉所有内容,第一个打印输出会返回我的预期。只要我包含第二个open语句(即使没有别的),它就不会写它。它是以某种方式重新排序开放的陈述或其他东西吗?

2 个答案:

答案 0 :(得分:5)

该行

ssize_t count = read(fp, buffer, strlen(buffer));

错了,你正在使用未初始化缓冲区的strlen。您可能希望缓冲区的大小如下:

ssize_t count = read(fp, buffer, sizeof buffer);

当你把它打印成一个字符串时,你应该确保缓冲区确实包含一个空终止的字符串。

if (fp != -1) // If file opened successfully
{

    off_t offset = lseek(fp, 2, SEEK_SET); // Seek from start of file
    ssize_t count = read(fp, buffer, sizeof buffer - 1);
    if (count > 0) // No errors (-1) and at least one byte (not 0) was read
    { 
       buffer[count] = 0;

答案 1 :(得分:0)

您是否完全确定每次运行时都清理文件?

如上所述,第一次运行时,您只能看到第二次打印输出,第二次看到第一次打印输出。