繁体   English   中英

从文件中读取多行关键字作为字符数组? 在C中

[英]Reading in multiple lines of keywords as character arrays from file? In C

嗨,我正在尝试从输入文件中读取文本行。 该文件可以包含多个关键字。 每个关键字由行尾分隔。 我可以假设关键字不能超过30个字符。 到目前为止,我只能阅读一个关键字,然后循环结束。 如何读取多个关键字,直到到达文件末尾。 我想将每个关键字存储到不同的字符数组中。 到目前为止,这就是我所拥有的。

char readKeywords()
{
    FILE *finn;
    char array2[30];
    int i = 0;
    finn = fopen("cp3Keywords.txt", "r");
    while (fscanf(finn, "%c", &array2[i]) != '\n')
    {
        i++;
    }

}

好的,您在这里遇到了几个问题。

  1. fscanf返回值是读取的项目数,在这种情况下,始终为1。

  2. 循环似乎打算在您读取换行符时结束,而不是在到达文件末尾时结束。

这样的事情怎么样:

int getNextKeyword(FILE *fp, char *result) {
    int c;
    while (EOF != (c = fgetc(fp))) {
        if (c == '\n') break;
        *result++ = c;
    }
    *result = 0;
    return c;
}

这会消耗直到下一个换行符或EOF的字符。 它将结果累积在提供的输入缓冲区中。 当您按下换行符或EOF时,您在缓冲区中写入了0,从而产生了一个以空值结尾的标准字符串。 它返回最后写入的字符。 然后,编写更多代码以循环方式调用此函数,直到返回EOF。

请注意变量c是int类型而不是char类型。 这是因为EOF(从fgetc返回的文件值的结尾)无法表示为字符。 因此,如果您编写char c; c = fgets(fp); if(c == EOF)...永远不会是真的。 这是一个常见的C编程错误。

因此,调用代码可能如下所示:

FILE *fp = fopen("cp3Keywords.txt", "r");
char array2[30];
while (EOF != readKeyword(fp, array2)) {
    // Do what you want to do with the keyword
}

您可以尝试如下操作:

while (fgets(array2, 30, finn)!= 0)
{
    puts(array2); //to print on screen, However you can copy it in separate array as per requirement.
}

您可以执行以下操作:

int readLine( FILE *stream, char *line )
{
    int i = 0;
    while( fscanf( stream, "%c", line + i ) != EOF )
    {
        if( line[i++] == '\n' )
        {
            line[i-1] = '\0';
            return 1;
        }
    }

    return 0;
}

int main( )
{
    const int KEYWORDS_COUNT = 100;
    char *keywords[KEYWORDS_COUNT];
    FILE *finn;
    int i = 0;

    finn = fopen( "plik.txt", "r" );
    do
    {
        keywords[i] = (char*)malloc( sizeof(char) * 31 );
    } while( readLine( finn, keywords[i++] ) );

    //free memory
    for( ; i > 0; i-- )
        free( keywords[i-1] );

    fclose( finn );

}

如果您不知道会有多少个关键字,可以随时重新分配关键字并将其复制到新数组中

在下面,您将找到一个可行的解决方案。 一旦了解了getline()函数,阅读关键字就很容易了。 棘手的部分是存储关键字。 由于您不知道会有多少个,因此需要使用动态分配的列表,然后需要对其进行迭代,清除等操作。

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

struct list_node{
    struct list_node *next;
    char *value;
};

struct list_node * appendToList(struct list_node *head, const char* keyword){
    //create new node and save value
    struct list_node *new_node, *node;
    new_node=calloc(sizeof(struct list_node),1); 
    if(!new_node){
        fprintf(stderr,"calloc() failed\n");
        return NULL;
    }
    new_node->value=strdup(keyword);

    //append new node to the tail of the list
    if(head){//head already exists, so append
        node=head;
        while(node->next)node=node->next;
        node->next=new_node;
    }else{ //appending first element
        head=new_node;
    }

    return head;
}
const char * getKeywordAtIndex(struct list_node *head, unsigned int index){
    const char *rv=NULL;
    if(head){ //basic sanity check
        while(index-->0){
            if(head->next)head=head->next;//walk the list
            else return NULL; //index too big
        }
        rv=head->value;
    }
    return rv;
}
void clearList(struct list_node *head){
    struct list_node *node;
    while(head){
        free(head->value);
        node=head->next;
        free(head);
        head=node;
    }
}
int main(){

    FILE *fp=fopen("keywords.txt","r");
    if(!fp){
        perror("Opening file failed");
        return 1;
    }

    char *lineptr=NULL;
    size_t buffer_len=0;
    ssize_t string_len;
    struct list_node *head=NULL;
    while((string_len=getline(&lineptr,&buffer_len,fp))!=-1){
        printf("line:%s\n",lineptr);
        if(lineptr[string_len-1]=='\n')lineptr[string_len-1]='\0';
        head=appendToList(head,lineptr);
    }
    free(lineptr);
    fclose(fp);
    int idx=0;
    const char *keyword;
    while((keyword=getKeywordAtIndex(head,idx++))!=NULL){
        printf("from list: %s\n",keyword);
    }
    clearList(head);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM