C语言文件操作

在C语言中,对文件的操作都通过标准库中的函数或宏来进行。标准库不是C语言本身的构成部分,但是支持标准C的实现都会提供该函数库中的函数声明、类型以及宏定义。比如,与文件操作相关的函数都定义在输入输出头文件<stdio.h>中。

流、缓存和文件

流(stream)不是缓存,也不等于文件。流是一种逻辑的、与设备无关的操纵多种外设方式,它把数据输入输出的操作对象(如磁盘文件或是物理设备的打印机、显示器、键盘等)都抽象化为一种“流”而不管其具体结构,这样涉及到流的操作函数都可用于各种对象,提高了编程的通用性。《C程序设计语言》中说“流是与磁盘或其他外围设备关联的数据的源或目的地,打开一个流,将把该流与一个文件或设备连接起来,关闭流将断开这种连接”。从代码的实现上来看,一个流可以由一个FILE结构来描述,而FILE结构里包含了指向缓冲区的指针和文件描述符,打开一个流时它通过指向缓冲区的指针和文件描述符来和缓存与文件(或设备)关联。更多的介绍还可以看这里这里

文件操作函数

FILE *fopen(const char *filename, const char *mode)
fopen函数打开filename指定的文件,并返回一个与之相关联的流。如果打开操作失败,则返回NULL。
继续阅读

字符串函数

几个常见字符串处理函数

/* *
 * str开头的函数部分
 * In the following functions,
 * variables s and t are of type char *;
 * cs and ct are of type const char *;
 * n is of type size_t;
 * and c is an int converted to char.
 */

/* strcpy - copy string ct to string s,
 including '\0'; return s. */
char *strcpy(char *s, const char *ct)
{
    char *tmp = s;

    while ((*tmp++ = *ct++) != '\0')
        /* nothing */;
    return s;
}

/* strcat - concatenate string ct to end of string s;
 return s. *
char *strcat(char * s, const char * ct)
{
    char *tmp = s;

    while (*tmp)
        tmp++;
    while ((*tmp++ = *ct++) != '\0')
        /* nothing */;

    return s;
}

/* strcmp - compare string cs to string ct,
 return <0 if cs<ct, 0 if cs==ct, or >0 if cs>ct. */
int strcmp(const char *cs,const char *ct)
{
    register signed char __res;

    while (1) {
        if ((__res = *cs - *ct++) != 0 || !*cs++)
            break;
    }

    return __res;
}

/* strlen - return length of cs. *
size_t strlen(const char *cs)
{
    const char *tmp;

    for (tmp = cs; *tmp != '\0'; ++tmp)
        /* nothing */;
    return tmp - cs;
}

/**
 * mem开头的函数部分
 * The mem... functions are meant for manipulating
 * objects as character arrays; the intent is an
 * interface to efficient routines.
 * In the following functions, s and t are of type void *;
 * cs and ct are of type const void *; n is of type size_t;
 * and c is an int converted to an unsigned char.
 */

/* memcpy - copy n characters from ct to s, and return s. */
void *memcpy(void *s, const void *ct, size_t n)
{
    char *dst = (char *)s, *src = (char *)ct;

    while (n--)
        *dst++ = *src++;

    return s;
}

/* memmove - same as memcpy except that it works even
 if the objects overlap. */
void *memmove(void *s, const void *ct, size_t n)
{
    char *dst, *src;

    if (s <= ct) {
        dst = (char *)s;
        src = (char *)ct;
        while (n--)
            *dst++ = *src++;
    } else {
        dst = (char *)s + n;
        src = (char *)ct + n;
        while (n--)
            *--dst = *--src;
    }

    return s;
}

/* memcmp - compare the first n characters of cs with ct;
 return as with strcmp. */
int memcmp(const void *cs, const void *ct, size_t n)
{
    const unsigned char *su1, *su2;
    signed char res = 0;

    for( su1 = cs, su2 = ct; 0 < n; ++su1, ++su2, n--)
        if ((res = *su1 - *su2) != 0)
            break;
    return res;
}

/* memset - place character c into first n
 characters of s, return s. */
void *memset(void *s, char c, size_t n)
{
    char *xs = (char *)s;

    while (n--)
        *xs++ = c;

    return s;
}