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

How do I read the contents of a file in C and store it into an array using fgets()?

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

f a q e g g e e e f


o e q e r t e w j o


t e e w 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]);
   }
}
}

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

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

#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] = '[=10=]';
        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 收集它的长度,通过用 [=17= 替换它来剥离它的 newline 字符](可选),使用 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 个字符。此外,在您的原始输入中,字符由 space 分隔 - 这不是必需的,实际上没有它会更容易。

value = fgets(stdin);真是个糟糕的表达!您根本不尊重 fgets 函数的语法。我的手册页说

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

所以在这里,因为你没有在正确的地方传递流,你可能会得到一个底层的 io 错误和 fgets returns NULL,它被转换为 int 0 值。然后下一个循环只是空操作。

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

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

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

FILE *fin=fopen("filename.txt", "r");
if(fin==NULL)
{
    perror("filename.txt not opened.");
}

在您的输入文件中,前几行有单个字母,每个字母由 space 分隔。

如果要将这些字母中的每一个都存储到 letters 字符数组中,可以使用以下循环加载每一行。

char c;
int i=0;
while(fscanf(fin, "%c", &c)==1 && c!='\n')
{
    if(c!=' ')
    {
        letters[i++]=c;
    }
}

这将只存储字母并且 不是 字符串,因为没有 [=19=] 字符。

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

您对 fgets() 函数的用法是错误的。

它的原型是

char *fgets(char *str, int n, FILE *stream);

参见 here

请注意,fgets() 也会将尾随的换行符 (\n) 存储到字符串中。你可能想删除它

str[strlen(str)-1]='[=13=]';

使用fgets()将底部的单词读入字符数组,将\n替换为[=19=]

并做

fgets(letters, sizeof(letters, fin);

当你想接受来自键盘的输入并存储到letters时,你在这里使用stdin而不是fin

请注意,fgets() 也会将尾随的换行符 (\n) 存储到 letters 中。你可能想删除它

letters[strlen(letters)-1]='[=15=]';


只是说,letters[i] 将是一个字符而不是字符串。

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

应该是

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

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

手头有一张地图来规划你的脚步总是好的。算法是一种软件地图。不过,在你计划你的步骤之前,你需要知道你要去哪里。

您设定的目标:

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 & f 用于创建存储)
g) 如何使用 fgets()。 (也许 google 搜索:How to use fgets
h) 使用feof()有什么需要注意的地方吗? (discussion and examaple feof)
i) 为什么在第二次调用 scanf 后我的输入不正确? (answer)

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