C语言 如何将文件中的单词保存到数组中?



***一些编辑: 整数关键词[16];

FILE *secretMessage;
secretMessage = fopen("C://Users/anyah/Fall2019/ECE_114/GreatGatsby.txt", "r");
char c;
char temp[100];
char temp2;
int i = 0;
int j = 0;

以上是我的变量的声明方式。 我使用了atoi((,因为我无法将单词保存到数组中

我需要搜索文本文件并找到字符"_"。下划线后面是一个需要放入数组中的单词。然后,我需要以与文本文件中找到的顺序相反的顺序打印单词数组。

我了解如何打开文件、创建数组和搜索字符 - 我无法弄清楚如何将找到的字符保存到字符串中,然后再保存到数组中。

while(1)
{
c = fgetc(secretMessage);
if (c == '_')
{
while(1)
{
temp2 = fgetc(secretMessage);
if (temp2 == ' ')
break;
else
{ 
temp[j] = temp2;
j++; 
};
}
int words = atoi(temp);
keywords[i] = words;
i++;
}
if (c==EOF)
break;
}

编译时我没有错误或警告 - 这是我当前的输出:

0 4200137 0 16 0 4200393 -1 -1 0 4200160 0 9900960 0 50 0 1

你可以做这样的事情:

char strings[100][100]; // array of 100 strings, each of them has no more than 99 meaningful characters
while () // outer loop by words
{
while () // inner loop by characters. Don't forget to check EOF here too!
{
strings[i][j] = temp2;
j++;
}
strings[i][j] = 0; // null-terminated string!
i++;
}
while () // printing loop by words
{
printf("%s", strings[i]);
}

"我知道如何打开文件,...">

不,不是真的,编码的一个基本规则是"不要硬编码文件名或使用魔术数字"。这意味着您不希望:

secretMessage = fopen("C://Users/anyah/Fall2019/ECE_114/GreatGatsby.txt", "r");

将参数传递给您的程序是您要main()参数的原因,例如

int main (int argc, char **argv)

只需提供要读取的文件名作为程序的参数(或默认从stdin读取(。为此,您可以执行类似于以下内容的操作:

#include <stdio.h>
...
int main (int argc, char **argv) {
...
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {  /* validate file open for reading */
perror ("file open failed");
return 1;
}

此时,您已完成打开文件(或正在从stdin读取(,并且已验证文件流是否已打开以供读取。

要在不动态分配存储的情况下存储多个单词,您需要使用一个 2D 数组,其中每行包含一个单词,并且列足以容纳任何单词加上nul 终止字符,以便该行中的字符数组可以被视为字符串。未删节词典中最长的非医学单词是 29 个字符(因此总列数为 30 即可,但32的下一个 2 次方就可以了(

由于在代码中不使用魔术数字,因此请根据需要#define一个或多个常量。您可以使用全局enum来完成相同的操作。要为 128 个 31 个字符或更少的单词提供存储空间,您可以执行以下操作:

/* if you need a constant, #define one (or more) */
#define ROWS 128    /* max no. of words to read  */
#define COLS 32     /* max no. of chars per-word */
...
char words[ROWS][COLS] = {""};  /* 2D array to hold words */

打开文件并声明存储以保存单词后,您现在只需用fgetc阅读每个字符(或一次阅读一行fgets(并收集字符,直到找到'_''n'EOF。为了保护words数组边界,请确保尝试填充不超过ROWS个单词。对于每个单词,您可以通过确保读取不超过COL-1个字符来保护列边界(-1以 nul 结尾字符节省空间(

将它们放在一起并使用几个计数器变量,您可以执行以下操作:

while (row < ROWS) {                /* while rows left in array */
int c, col = 0;                 /* character c, column counter */
/* loop over each char in word */
for (c = fgetc(fp); col < COLS - 1; col++, c = fgetc(fp)) {
if (c == EOF)               /* if EOF jump out of nested loops */
goto done;
if (c == '_' || c == 'n')  /* if char is '_' or 'n', get next */
break;
words[row][col] = c;        /* assign char to current word */
}
words[row++][col] = 0;          /* nul-terminate, advance word count */
}
done:;      /* goto label to jump to */

(注意:跳出嵌套循环的唯一直接方法是使用旧的goto语句。唯一的限制是你不要试图跳出函数,打破嵌套循环是可以的(

一个完整的示例可以是:

#include <stdio.h>
/* if you need a constant, #define one (or more) */
#define ROWS 128    /* max no. of words to read  */
#define COLS 32     /* max no. of chars per-word */
int main (int argc, char **argv) {
char words[ROWS][COLS] = {""};  /* 2D array to hold words */
int row = 0, i;                 /* row (word) and loop counter */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {  /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (row < ROWS) {                /* while rows left in array */
int c, col = 0;                 /* character c, column counter */
/* loop over each char in word */
for (c = fgetc(fp); col < COLS - 1; col++, c = fgetc(fp)) {
if (c == EOF)               /* if EOF jump out of nested loops */
goto done;
if (c == '_' || c == 'n')  /* if char is '_' or 'n', get next */
break;
words[row][col] = c;        /* assign char to current word */
}
words[row++][col] = 0;          /* nul-terminate, advance word count */
}
done:;      /* goto label to jump to */
if (fp != stdin)   /* close file if not stdin */
fclose (fp);
for (i = row-1; i >= 0; i--)
printf ((i != row - 1) > 0 ? " %s" : "%s", words[i]);
putchar ('n');
}

最后一个循环只是以相反的顺序输出单词,而printf语句中的三元只是确保您不会在第一个单词输出之前打印空格。

示例输入文件

$ cat dat/backwardsfleas.txt
cat_lucky_none_has_cat_my_fleas_has_dog_my

示例使用/输出

$ ./bin/arrayrevwords dat/backwardsfleas.txt
my dog has fleas my cat has none lucky cat

仔细查看,如果您有其他问题,请告诉我。

相关内容

  • 没有找到相关文章

最新更新