用c语言编写getline函数

时间:2015-08-08 08:10:56

标签: c

我正在尝试从file.txt读取一行,并将其作为字符串maxchar返回,而不使用getline()

例如,如果file.txt包含

c language 
language c

然后:

printf("%s\n",get_line(f,3)) 
printf("%s\n",get_line(f,3))

将返回

c l
lan

但我的代码会返回奇怪的字符。

#include <stdio.h>
#include <stdlib.h>

char* get_line(FILE* f, int maxchar){

    char* string = (char*)malloc(sizeof(f));
    int c;
    int i;

    while((c = fgetc(f)) != EOF && c != '\n'){
            fgets(string,maxchar,f);

    }
    return string;          
}


int main(void){
    FILE* f;
    f = fopen("file.txt","r");
    printf("%s\n %s\n",get_line(f,3),get_line(f,5));

    fclose(f);
    return 0;
}

阅读文件有什么不对吗?或使用fgetc()

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

好的,不得不测试一下。更多改进。

#include <stdio.h>
#include <stdlib.h>

char* get_line(FILE* f, int maxchar){

    char* string = malloc(maxchar+1);
    int c;
    int i = 0;

    while ((c = fgetc(f)) != EOF && c != '\n' && i < maxchar){
        *(string + i++) = c;
    }
    *(string + i) = '\0';
    return string;
}


int main(void){
    FILE* f;
    f = fopen("file.txt", "r");
    printf("%s\n", get_line(f, 3)); 
    printf("%s\n", get_line(f, 5));

    fclose(f);
    return 0;
}

原因:

printf("%s\n %s\n",get_line(f,3),get_line(f,5));

给出意想不到的结果是由于函数参数的评估顺序。在使用cdecl的C中,printf的实际参数从右到左进行计算。 printf如何处理这个你必须查看代码。更可靠的是使用两行作为我的例子。

您的malloc行是错误的,因为您需要为字符数分配空间,而sizeof FILE *将返回指针的大小,而不是您想要的。您还可以检查文件字节大小并将其用作maxchar。

你对fgets的使用也是错误的。

在循环中,您将拥有一个char数组,例如:

'c','','l','a','n'

后跟随机值(因为你没有为malloc'd缓冲区预先赋值。所以行:

*(string + i) = '\0';

在字符串的末尾添加一个空字符,使其成为一个空终止的c字符串 - 这是C字符串函数所期望的。

为清楚起见,*(string + i)表示您获取字符串的地址,添加i和取消引用(星号 - *是取消引用运算符)。

= '\0'

在字符串的末尾附加空字符。

答案 1 :(得分:1)

本声明

char* string = (char*)malloc(sizeof(f));

没有意义。您需要为大小为maxchar的字符串分配内存。

关于这个循环也可以这么说

while((c = fgetc(f)) != EOF && c != '\n'){
        fgets(string,maxchar,f);

您应该使用fgetcfgets

可以使用fgetc

以下列方式编写该函数
char * get_line( FILE *f, size_t maxchar )
{
    char *record = NULL;

    if ( maxchar && !feof( f ) && ( record = malloc( maxchar ) ) != NULL )
    {
        int c;
        size_t i = 0;

        while ( i < maxchar - 1 && ( c = fgetc( f ) ) != EOF && c != '\n' ) 
        {
            record[i++] = c;
        }

        record[i] = '\0';
    }

    return record;          
}

并且不要忘记在节目结束前释放主要唱片。例如

char *s;

if ( ( s = get_line(f,3) ) != NULL ) printf( "%s\n", s );
free( s );


if ( ( s = get_line(f,5) ) != NULL ) printf( "%s\n", s );
free( s );

更好的方法是按以下方式声明函数

char * get_line( FILE *f, char *s, size_t maxchar );

在这种情况下,您可以在main中声明一个字符数组,并将其传递给函数。

例如

char * get_line( FILE *f, char *s, size_t maxchar )
{
    size_t i = 0;

    if ( maxchar )
    {
        int c;

        while ( i < maxchar - 1 && ( c = fgetc( f ) ) != EOF && c != '\n' ) 
        {
            s[i++] = c;
        }
    }

    s[i] = '\0';

    return s;          
}

主要可以是

#define MAX_CHAR 80
//...
int main( void )
{
    char s[MAX_CHAR];

    //...

    printf( "%s\n", get_line( f, s, 3 ) );

    printf( "%s\n", get_line( f, s, 5 ) );

    //...