如何使用fgets()读取C中文件的内容并将其存储到数组中?

时间:2017-09-26 23:27:52

标签: c arrays stdin fgets feof

所以我需要创建一个单词搜索程序,它将读取包含字母的数据文件,然后在最后找到需要找到的单词 例如:

f a q e g g e e f

o e e t t w w o

t q e r t y u

政府

自由

并且字母和单词的列表更长,但无论如何我需要将字母保存到数组中并且我遇到困难,因为它从不存储正确的数据。这是我到目前为止所拥有的

#include <stdio.h>

int main()
{
int value;
char letters[500];

while(!feof(stdin))
{
   value = fgets(stdin);

   for(int i =0; i < value; i++)
   {
      scanf("%1s", &letters[i]);
   }

   for(int i=0; i<1; i++)
   {
      printf("%1c", letters[i]);
   }
}
}

我也不知道在将字符放入数组之后,我将如何将单词存储到单独的数组中。

4 个答案:

答案 0 :(得分:1)

存储带有字符或单词的行的一种方法是将它们存储在指向数组的指针数组中 - 行,

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

#define MAXLET 500
#define MAXLINES 1000

int main()
{
    char *lptr;
    // Array with letters from a given line
    char letters[MAXLET];
    // Array with pointers to lines with letters
    char *lineptr[MAXLINES];

    // Length of current array
    unsigned len = 0;
    // Total number of lines
    int nlines = 0;

    // Read lines from stdin and store them in 
    // an array of pointers
    while((fgets(letters,MAXLET,stdin))!=NULL)
    {
        len = strlen(letters);
        letters[len-1] = '\0';
        lptr = (char*) malloc(len);
        strcpy(lptr, letters);
        lineptr[nlines++]=lptr;
    }

    // Print lines
    for (int i = 0; i < nlines; i++)
        printf("%s\n", lineptr[i]);

    // Free allocated memory
    for (int i = 0; i < nlines; i++)
        free(lineptr[i]);
}

在下文中,指向stdin的每一行的指针存储在lineptr中。存储后,您可以访问和操作每一行 - 在这个简单的例子中,我只是逐个打印它们,但稍后会显示简单操作的示例。最后,程序释放先前分配的内存。一旦不再使用已分配的内存,这是一个很好的做法。

存储一行的过程包括从stdin获取每一行,使用strlen收集它的长度,通过替换剥离它的newline字符使用\0(可选),使用malloc为其分配内存,最后将指针存储到lineptr中的内存位置。在此过程中,程序还会计算输入行的数量。

您可以为两个输入实现此序列 - 字符和单词。它将产生干净,随时可用的输入。您还可以考虑将行集合移动到一个函数中,这可能需要使lineptr类型数组全局化。如果您有任何问题,请告诉我。

要记住的是,对于给定的数据集,可能必须增加MAXLET,特别是MAXLINESMAXLINES 1000字面上假设您不会超过1000行) 。

此外,在Unix和Mac上,此程序允许您使用$ prog_name < in_file从文件中读取,可以很容易地修改它以直接从文件中读取。

以下是一些用法示例 - lineptr存储指向每一行(数组)的指针,因此程序首先检索指向一行的指针,然后像任何数组一样继续:

// Print 3rd character of each line
// then substitute 2nd with 'a'
char *p;
for (int i = 0; i < nlines; i++){
    p = lineptr[i];
    printf("%c\n", p[2]);
    p[1] = 'a';
}

// Print lines
for (int i = 0; i < nlines; i++)
    printf("%s\n", lineptr[i]);

// Swap first and second element
// of each line
char tmp;
for (int i = 0; i < nlines; i++){
    p = lineptr[i];
    tmp = p[0];
    p[0] = p[1];
    p[1] = tmp;
}

// Print lines
for (int i = 0; i < nlines; i++)
    printf("%s\n", lineptr[i]);

请注意,这些示例只是一个演示,并假设每行至少有3个字符。此外,在您的原始输入中,字符由空格分隔 - 这是不必要的,事实上如果没有它,它会更容易。

答案 1 :(得分:1)

你说你想从数据文件中读取。如果是这样,您应该打开文件。

letters

在输入文件中,前几行有单个字母,每个字母用空格分隔。

如果要将每个字母存储到char c; int i=0; while(fscanf(fin, "%c", &c)==1 && c!='\n') { if(c!=' ') { letters[i++]=c; } } 字符数组中,可以使用以下循环加载每一行。

\0

这只会存储字母,而不是字符串,因为没有fgets()字符。

阅读底部的单词可以使用fgets()完成。

您对char *fgets(char *str, int n, FILE *stream); 功能的使用是错误的。

它的原型是

fgets()

请参阅here

请注意,\n也会将尾随换行符(str[strlen(str)-1]='\0'; )存储到字符串中。您可能希望将其删除,如

fgets()

使用\n将底部的字词读入字符数组,并将\0替换为fgets(letters, sizeof(letters, fin);

并做

stdin

如果您想接受键盘输入并存储到fin,请使用letters代替fgets()

请注意,\n也会将尾随换行符letters也存储到letters[strlen(letters)-1]='\0'; 中。您可能希望将其删除,如

letters[i]

<小时/> 只是说,scanf("%1s", &letters[i]); 将是一个字符,而不是一个字符串。

scanf("%c", &letters[i]);

应该是

{{1}}

答案 2 :(得分:1)

您帖子中的代码似乎与您的既定目标不符,并表示您尚未掌握正在使用的功能的正确应用。
你已经表达了一个想法,描述了你想做什么,但你采取的步骤(至少显示的那些步骤)不会让你到那里。差远了。

手头有一张地图计划你的步骤总是好的。算法是一种软件映射。在您计划步骤之前,您需要知道自己的目标。

您的既定目标:

1) Open and read a file into lines.    
2) Store the lines, somehow. (using fgets(,,)?)     
3) Use some lines as content to search though.  
4) Use other lines as objects to search for  

要回答的一些问题:

a)如何将搜索内容与要搜索的字符串区分开来    呢?
       b)如何存储搜索内容?
       c)如何存储搜索词?        d)如何进行内容和搜索词之间的比较?
       e)文件中有多少行? ( example
       f)最长线的长度? ( discussion and example )(用于创建存储的e&amp; f)
       g)如何使用fgets()。 (也许谷歌搜索: How to use fgets
       h)使用feof()时是否有注意事项? ( discussion and examaple feof
       i)为什么我的输入不是在第二次调用scanf之后? ( answer

完成识别并明确目标中的项目列表,然后回答这些(可能还有其他)问题。此时,您将准备开始确定实现目标的步骤。

答案 3 :(得分:0)

value = fgets(stdin);是一个可怕的表达!您并不尊重fgets函数的所有语法。我的手册页说

  

char * fgets(char * restrict str, int size, FILE * restrict stream);

所以在这里,因为你没有在正确的位置传递流,你可能会得到一个潜在的io错误,fgets返回NULL,它被转换为int 0值。然后下一个循环只是一个无操作。

使用fgets读取行的正确方法是:

if (NULL == fgets(letters, sizeof(letters), stdin) {
    // indication of end of file or error
    ...
}
// Ok letters contains the line...