简体   繁体   English

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

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

Hi I am trying to read in lines of text from an input file. 嗨,我正在尝试从输入文件中读取文本行。 The file can contain multiple keywords. 该文件可以包含多个关键字。 Each keyword is seperated by an end of line. 每个关键字由行尾分隔。 I can assume the keywords wont be longer than 30 characters. 我可以假设关键字不能超过30个字符。 So far I am able to readon only one keyword and then my loop ends. 到目前为止,我只能阅读一个关键字,然后循环结束。 How do I read multiple keywords until I reach the end of file. 如何读取多个关键字,直到到达文件末尾。 I want to store each keyword into different character arrays. 我想将每个关键字存储到不同的字符数组中。 This is what I have so far. 到目前为止,这就是我所拥有的。

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

}

OK, you've got several problems here. 好的,您在这里遇到了几个问题。

  1. The fscanf return value is the number of items read, which in this case will always be 1. fscanf返回值是读取的项目数,在这种情况下,始终为1。

  2. The loop seems intended to end when you read the newline, not when you reach end of file. 循环似乎打算在您读取换行符时结束,而不是在到达文件末尾时结束。

How about something like this: 这样的事情怎么样:

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

This consumes characters up to the next newline or EOF. 这会消耗直到下一个换行符或EOF的字符。 It accumulates the result in the input buffer provided. 它将结果累积在提供的输入缓冲区中。 When you hit the newline or EOF, you write a 0 in the buffer, thus resulting in a standard null-terminated string. 当您按下换行符或EOF时,您在缓冲区中写入了0,从而产生了一个以空值结尾的标准字符串。 It returns the last character written. 它返回最后写入的字符。 Then you write some more code that calls this function in a loop until it returns EOF. 然后,编写更多代码以循环方式调用此函数,直到返回EOF。

Please notice how the variable c is type int, not type char. 请注意变量c是int类型而不是char类型。 That's because EOF (the end of file value returned from fgetc) is not representable as a character. 这是因为EOF(从fgetc返回的文件值的结尾)无法表示为字符。 So if you write char c; 因此,如果您编写char c; c = fgets(fp); c = fgets(fp); if (c == EOF) ... it will never be true. if(c == EOF)...永远不会是真的。 This is a common C programming mistake. 这是一个常见的C编程错误。

So the calling code might look like this: 因此,调用代码可能如下所示:

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

You can try something like this: 您可以尝试如下操作:

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

You could do something like this: 您可以执行以下操作:

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 );

}

If you don't know how many keywords there will be you can always realloc and copy keywords to new array 如果您不知道会有多少个关键字,可以随时重新分配关键字并将其复制到新数组中

Below you'll find a working solution. 在下面,您将找到一个可行的解决方案。 Reading keywords is easy once you know about getline() function. 一旦了解了getline()函数,阅读关键字就很容易了。 The tricky part is storing the keywords. 棘手的部分是存储关键字。 Since you don't know how many there will be, you need to use a dynamically allocated list, which then you need to iterate over, clear, etc. 由于您不知道会有多少个,因此需要使用动态分配的列表,然后需要对其进行迭代,清除等操作。

#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