APUE2e之Exercise 3.6

17 篇文章 0 订阅
11 篇文章 0 订阅

I was working exercise3.6 of APUE2e and the code was simple. But when I tried to use fgets and fputs to print out the file content, I got problems. Then I tried to figure out the reason. It turned out to be the null or ‘’ byte of C string, which prevent fgets and fputs from behaving as I expected (fgets appends null byte to the end of input buffer, while fputs prints null-terminated string). I solved the problem by preventing write function to write the null or ‘‘ byte for a C string to the file. This was done by restricting the number of bytes to be writen (using sizeof(buffer)-1, rather than sizeof(buffer)). These findings reminded me of my careless reading, because the problem was caused by a really small mistake. Now I learned the lesson. I prefer reading to writing codes. But through writing and testing, I learn more than just reading. I think I must do more coding and don’t get satisfied just by reading the books and codes.

Attaching is the code I wrote for exercise3.6.


/*
 * exercise3-6.c
 *
 *  Created on: Sep 10, 2011
 *      Author: zhuhuang
 */
 
#include <apueerr.h>
#include <fcntl.h>
 
int main(void)
{
	int filedes;
	FILE *fileptr;
	int writenum;
	int readnum;
	off_t seekpos;
	int character;
 
	char buffer0[] = "test";
    printf("Size of buffer0: %dn", sizeof(buffer0)); //sizeof includes the ''
 
	char buffer1[] = "The first sentence of file3-6 (Using the write function to write).n"; //an '' in the end
	char buffer2[20];
	char buffer3[] = "The second sentence of file3-6 (Using the write function to write).n";  //an '' in the end
	char buffer4[69];
 
	if((filedes = open("file3-6", O_CREAT | O_RDWR | O_APPEND | O_TRUNC, S_IRWXU | S_IRGRP | S_IROTH)) == -1)
		err_sys("open error");
 
	if((writenum = write(filedes, buffer1, sizeof(buffer1)-1)) == -1)  //Not "sizeof(buffer1)", otherwise it will cause fputs to behave weirdly.
		err_sys("write error 1");
	printf("Number of characters of first write: %dn", writenum);
 
	if((seekpos = lseek(filedes, 0, SEEK_CUR)) == -1)
		err_sys("lseek error 1");
	printf("Current file offset after the first write: %dn", (int)seekpos);
 
	if((seekpos = lseek(filedes, 10, SEEK_SET)) == -1)
		err_sys("lseek error 2");
	printf("lseek the current file offset to: %dn", (int)seekpos);
 
	if((readnum = read(filedes, buffer2, 20)) == -1)
		err_sys("read error");
	printf("The string that has been read: %sn", buffer2);
 
	if((seekpos = lseek(filedes, 0, SEEK_CUR)) == -1)
		err_sys("lseek error 3");
	printf("Current file offset after the first read: %dn", (int)seekpos);
 
	if((writenum = write(filedes, buffer3, sizeof(buffer3)-1)) == -1)
		err_sys("write error 2");
	printf("Number of characters of second write: %dn", writenum);
 
	if((seekpos = lseek(filedes, 0, SEEK_CUR)) == -1)
		err_sys("lseek error 4");
	printf("Current file offset after the second write: %dn", (int)seekpos);
 
	if((seekpos = lseek(filedes, 68, SEEK_SET)) == -1)
		err_sys("lseek error 2");
	printf("lseek the current file offset to: %dn", (int)seekpos);
 
	if((readnum = read(filedes, buffer2, 20)) == -1)
		err_sys("read error");
	printf("The string that has been read: %sn", buffer2);
 
	if((seekpos = lseek(filedes, 0, SEEK_CUR)) == -1)
		err_sys("lseek error 3");
	printf("Current file offset after the second read: %dn", (int)seekpos);
 
	//Problem: fail to give the complete content of the file.
	//Depending on the size of buffer4, the output can be only contents of buffer1, or contents of buffer1 and part of buffer3.
 
	//No matter how big we have set the size of buffer4 to and whether we use the fflush and fsync function, the problem remains.
	//The problem is caused by null or '' byte.
 
	printf("The contents of the file file3-6:n");
	if((fileptr = fopen("file3-6", "r")) == NULL)
		err_sys("fopen error");
 
	//fgets read at most 40-1 characters, a null or '' byte is inserted to the end.
	while(fgets(buffer4, 40, fileptr) != NULL){
		//fputs writes the null-terminated string.
		//The null or '' causes fputs to behave unexpectedly.
		if(fputs(buffer4, stdout) == EOF)
			err_sys("fputs error");
		//fputs(buffer4, stdout); //Not the flushing problem.
		//fflush(stdout);
		//fsync(STDOUT_FILENO);
	}
 
	if(ferror(fileptr))
		err_sys("fgets error");
 
	exit(0);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值