c - 我正在尝试搜索文件计数。使用二分搜索遇到 ‘C’ 个保留字

标签 c arrays binary-search file-handling

我正在用 c 语言编写一个程序,该程序搜索源代码文件并计算遇到的“C”保留字的数量。但仅当输入的保留字是第一个字时,才会打印保留字。它计算的是字符串总数,而不是使用的保留字总数。有人可以帮我解决这个问题吗?我的代码太乱了,请不要介意。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define KEYMAX 32


FILE *fp ;
char data[1024];
struct keyword
{
    char word[10];
    int occur;
};
int i = 0, j = 0, pos;
char str[100], unit[20], ch;
int stored[1024];
char delimiters[] = " \t\n\v\f\r";  /* possible space delimiters */
char *token;
struct keyword key[32] = {"auto", 0, "break", 0, "case", 0,
                          "char", 0, "const", 0, "continue", 0,
                          "default", 0, "do", 0, "double", 0,
                          "else", 0, "enum", 0, "extern", 0,
                          "float", 0, "for", 0, "goto", 0,
                          "if", 0, "int", 0, "long", 0,
                          "register", 0, "return", 0, "short", 0,
                          "signed", 0, "sizeof", 0, "static", 0,
                          "struct", 0, "switch", 0, "typedef", 0,
                          "union", 0, "unsigned", 0, "void", 0,
                          "volatile", 0, "while", 0,};

int main()
{
    takeinput();
    system("CLS");
    theresult();
    // processresult();
    // ctoken();
return (0);

}

int takeinput()    // function to write in the file
{

  printf( "**********Welcome*************" ) ;
    fp = fopen("test.c", "w") ;   // Open file in write mode.
    if ( fp == NULL )
    {
        printf( "Could not open file test.c" ) ;  // Prints the statement if the file is not able to open.
        return 1;
    }
    printf( "\nPlease enter some text from keyboard to write in the file test.c \n\t" ) ;
    // getting input from user
    while ( strlen ( gets( data ) ) > 0 )
    {
        // writing in the file
        fputs(data, fp) ;           // Writes to file
        fputs("\n", fp) ;
    }

    // closing the file
    fclose(fp) ;
    return 0;
}

int theresult()
{

   fp = fopen("test.c", "r"); // read mode

   if (fp == NULL)
   {
      perror("Error while opening the file.\n");   // Prints the statement if the file is not able to open.
      return 1;
   }
   printf("The contents of test.c file are:\n");

 // To covert the ch into str
   int i= 0;
  //  printf("-----this is from ch----\n"); (Just for reference)
   while((ch = fgetc(fp)) != EOF)
   {
    str[i]=ch;
    i++;

   //  printf("%c",ch);   prints character

   }

   printf("%s",str);

   // printf("\n----This is from token-----\n");   (just for reference)
   for (token = strtok(str, delimiters); token != NULL;
         token = strtok(NULL, delimiters)) /* 'for loop' conditional part */
        /* prints token one per line */
       // puts(token);      // prints token

    for (i = 0; i < strlen(str); i++)
    {
        while (i < strlen(str) && str[i] != ' ' && isalpha(str[i]))
        {
            unit[j++] = tolower(str[i++]);
        }
        if (j != 0)
        {
            unit[j] = '\0';
            pos = binarysearch(unit, key);
            j = 0;
            if (pos != -1)
            {
               key[pos].occur++;
            }
        }
    }
    printf("***********************\n   Keyword\tCount\n***********************\n");
    for (i = 0; i < KEYMAX; i++)
    {
        if (key[i].occur)
        {
            printf("  %s\t  %d\n", key[i].word, key[i].occur);       // Prints the reserved keyword and its occurance
        }
    }

    fclose(fp);
   return (0);
}



int binarysearch(char *word, struct keyword key[])
{
    int low, high, mid;

    low = 0;
    high = KEYMAX - 1;
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (strcmp(word, key[mid].word) < 0)
        {
            high = mid - 1;
        }
        else if (strcmp(word, key[mid].word) > 0)
        {
            low = mid + 1;
        }
        else
        {
            return mid;
        }
    }
    return -1;
}

输入的字符串是:如果我中断,请重新加入它。 float float

<小时/>

关键字计数

<小时/>
if            1 
break     1
Float     2

最佳答案

错误出现在函数 theresult 中。在用于标记化输入的 for 循环中,您处理并从整个输入 str 中搜索单词,而不是从 返回的单词 token strtok。标记化后,您不必检查空格 (' '),因为空格是分隔符的一部分。

将循环更改为后似乎对我有用:

   for (token = strtok(str, delimiters); token != NULL;
         token = strtok(NULL, delimiters)) /* 'for loop' conditional part */
        /* prints token one per line */
       // puts(token);      // prints token

        for (i = 0; i < strlen(token); i++)
        {
            while (i < strlen(token) && token[i] != ' ' && isalpha(token[i]))
            {
                unit[j++] = tolower(token[i++]);
            }
            if (j != 0)
            {
                unit[j] = '\0';
                pos = binarysearch(unit, key);
                j = 0;
                if (pos != -1)
                {
                   key[pos].occur++;
                }
            }
        }

输出为

The contents of test.c file are:
if i break please re-join it. float float
***********************
   Keyword      Count
***********************
  break   1
  float   2
  if      1

补充说明:

我建议不要将整个输入文件读取到 str 中,而是使用 fgets 和循环逐行读取和处理输入。

如果您希望用户输入输入文本,您可以直接处理输入行,而不是先将它们写入文件“test.c”,然后读取该文件。

标记化后的 while 循环将切断第一个非字母字符的所有内容。也许您实现此操作是因为它由于原始错误而不起作用。当 token 为“re-join”时,它将搜索“re”。您应该检查这是否是您想要的,并在必要时更改 while 循环。

关于c - 我正在尝试搜索文件计数。使用二分搜索遇到 ‘C’ 个保留字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55901727/

相关文章:

c++ - 字符串输出中的奇数字符C++

c# - List<T> 上的 BinarySearch 似乎返回了奇怪的结果

python - 在 Python 中,使用二分法在字典列表中查找项目

c - 无法解码一段代码及其用途

我可以使用列表重置数组值吗?

javascript - 在 JavaScript 对象数组中按 id 查找对象

java - 二分查找平方根[作业]

c - 如何计算黎明/黄昏时间

c++ - 优化 O_DIRECT 写入

javascript - 如何根据他的第二个子数组值获得最大的数组元素