输出三个hello

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAX 100

int read_line(int fd, char *buf, int count)
{
	int i;
	char ch;

	for(i = 0; i < count; i++)
	{
        if((read(fd,&ch,1)) < 0)
		{
			perror("read error!\n");
			exit(1);
		}

		if(ch == '\n')
		{
             buf[i] = '\0';
			 return i;
		}

		buf[i] = ch;
	}

	buf[i - 1] = '\0';
	
	return count;
}

int main()
{
	int i;
	int fd;
	int w_count;
	int r_count;
	char filename[MAX];

	char r_buf[MAX];
	char w_buf[MAX];

	printf("Please input filename:\n");
	scanf("%s",filename);

	if((fd = open(filename, O_CREAT | O_RDWR, 0755)) < 0)
	{
		perror("open error!\n");
		exit(1);
	}

	
    for(i = 0; i < 3; i++)
	{
        memset(w_buf,0,sizeof(w_buf));
		scanf("%s",w_buf);
		
		if((w_count = write(fd,w_buf,strlen(w_buf))) < 0)
		{
			perror("write error!\n");
			exit(1);
		}
		else
		{
			write(fd,"\n",1);
		}
	}
    
    lseek(fd,0,SEEK_SET);
#if 0
	if((r_count = read(fd,r_buf,sizeof(r_buf))) < 0)
	{
		perror("read error!\n");
		exit(1);
	}
	else
	{
		r_buf[w_count * 3 + 3] = '\0';
		printf("read data: %s\n",r_buf);
	}
#endif

	for(i = 0; i < 3; i++)
	{
        memset(r_buf,0,sizeof(r_buf));
		read_line(fd,r_buf,100);
		printf("read data: %s\n",r_buf);
	}

	close(fd);

	return 0;
}

memset函数及其用法

定义变量时一定要进行初始化,尤其是数组和结构体这种占用内存大的数据结构。在使用数组的时候经常因为没有初始化而产生“烫烫烫烫烫烫”这样的野值,俗称“乱码”。

每种类型的变量都有各自的初始化方法,memset() 函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行初始化工作。它是直接操作内存空间,mem即“内存”(memory)的意思。该函数的原型为:

include <string.h>

void *memset(void *s, int c, unsigned long n);

函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。

memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。

memset 一般使用“0”初始化内存单元,而且通常是给数组或结构体进行初始化。一般的变量如 char、int、float、double 等类型的变量直接初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦。

当然,数组也可以直接进行初始化,但 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。

这时有人会问:“字符串数组不是最好用’\0’进行初始化吗?那么可以用 memset 给字符串数组进行初始化吗?也就是说参数 c 可以赋值为’\0’吗?”

可以的。虽然参数 c 要求是一个整数,但是整型和字符型是互通的。但是赋值为 ‘\0’ 和 0 是等价的,因为字符 ‘\0’ 在内存中就是 0。所以在 memset 中初始化为 0 也具有结束标志符 ‘\0’ 的作用,所以通常我们就写“0”。

memset 函数的第三个参数 n 的值一般用 sizeof() 获取,这样比较专业。注意,如果是对指针变量所指向的内存单元进行清零初始化,那么一定要先对这个指针变量进行初始化,即一定要先让它指向某个有效的地址。而且用memset给指针变量如p所指向的内存单元进行初始化时,n 千万别写成 sizeof§,这是新手经常会犯的错误。因为 p 是指针变量,不管 p 指向什么类型的变量,sizeof§ 的值都是 4。

下面写一个程序:

# include <stdio.h>
# include <string.h>
int main(void)
{
    int i;  //循环变量
    char str[10];
    char *p = str;
    memset(str, 0, sizeof(str));  //只能写sizeof(str), 不能写sizeof(p)
    for (i=0; i<10; ++i)
    {
        printf("%d\x20", str[i]);
    }
    printf("\n");
    return 0;
}

根据memset函数的不同,输出结果也不同,分为以下几种情况:
memset(p, 0, sizeof§); //地址的大小都是4字节
0 0 0 0 -52 -52 -52 -52 -52 -52

memset(p, 0, sizeof(*p)); //*p表示的是一个字符变量, 只有一字节
0 -52 -52 -52 -52 -52 -52 -52 -52 -52

memset(p, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0

memset(str, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0

memset(p, 0, 10); //直接写10也行, 但不专业
0 0 0 0 0 0 0 0 0 0

posted on 2022-02-25 16:10  慧茗子  阅读(19)  评论(0)    收藏  举报  来源