【问题标题】:Incorrect usage of a for loop in strstr() in CC 中 strstr() 中 for 循环的错误使用
【发布时间】:2014-06-10 07:51:53
【问题描述】:

我正在尝试学习 C 中的字符串处理。我编写了一个程序,该程序存储了一些音乐曲目,并帮助用户检查他/她想到的歌曲是否存在于存储的曲目中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr() 函数检查输入的单词/文本是否与任何轨道上的任何单词/文本匹配,如果匹配,则显示轨道号和名称。

我编写的代码一开始就可以正常运行。但是有一个很大的缺陷,这是由于 for 循环的错误使用造成的。我将首先展示程序和两个输出 -

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

//Define tracks array
char tracks[][80]={     //[][80] is a 2D array- for storing tracks and the size of each track, which is 80 at max
"I left my heart in Harvard med school",
"Newark, Newark- a wonderful town",
"Dancing with a dork",
"From here to maternity",
"The girl from Iwo Jima",
};

//Define function to search for text in tracks array

void findTrack(char search_for[])
{
    int i;
    for(i = 0; i < 5; i++)
    {
       if(strstr(tracks[i], search_for))    
       {
          printf("\n Match found\n");       
          printf("\n Track[%i]: %s\n", i, tracks[i]);
          break;
       }
       else
           printf("\n No matching tracks found!");
       }
}

int main()
{
   char search_for[80];
   printf("\n Enter the text to search:\n");
   scanf("%79s", search_for);
   findTrack(search_for);
   return 0;
}

第一个输出-

 Enter the text to search:
Harvard

 Match found

 Track[0]: I left my heart in Harvard med school

如您所见,此输出是正确的。 Harvard 这个词出现在我存储在 tracks 数组中的第一首曲目中。这是在 findTrack 函数内的 for loop 的第一次迭代中发现的,因此输出正确。

但是,如果我再次运行程序,这次我将要搜索的文本指定为town,结果输出是 -

第二个输出-

Enter the text to search:
town

 No matching tracks found!
 Match found

 Track[1]: Newark, Newark- a wonderful town

发生这种情况是因为在for 循环的第一次迭代中,即:tracks[0]strstr 没有找到任何匹配项,因此它在循环的else 部分打印了语句。当循环完成迭代 1 时,对于 tracks[1],在 town 中找到了匹配项,因此它打印了循环的 if 部分。

同样,如果我再次运行程序并将Jima 作为要搜索的文本,则输出为-

 Enter the text to search:
Jima

 No matching tracks found!
 No matching tracks found!
 No matching tracks found!
 No matching tracks found!
 Match found

 Track[4]: The girl from Iwo Jima 

我认为这个缺陷是由于不正确的 for 循环造成的。但我不确定如何正确使用 for 循环。任何有关纠正此问题的建议将不胜感激。 谢谢!

编辑

在我的代码中,我使用for 循环和i&lt;5,因为我知道我的程序中存储了5 tracks。但是,更好的编码方式是运行一个循环,而不考虑/在不知道轨道数量的情况下。这可能发生在我的轨道数量发生变化的情况下,因此每次都保持更改 for 循环效率低下。有关如何实施此更改的任何建议?

【问题讨论】:

  • 您可以将字符串数组声明为char *tracks[] = {"xxx","yyy",..., NULL},那么您不需要知道有多少字符串,因为您可以循环直到找到NULL。 for (i = 0; tracks[i] != NULL; ++i)

标签: c string loops strstr


【解决方案1】:

您只想在检查整个数组tracks 是否匹配后打印Not found。所以你可以使用一个标志并在循环后检查它:

void findTrack(char search_for[])
{
  int i;
  int found = 0;
  for(i=0;i<5;i++)
  {
    if(strstr(tracks[i], search_for))   
    {
    found = 1;
    printf("\n Match found\n");     
    printf("\n Track[%i]: %s\n", i, tracks[i]);
    break;
    }
  }
  if (!found)     printf("\n No matching tracks found!");
}

【讨论】:

  • 从 C99 开始,C 实际上有一个 bool 类型,以及 truefalse 字面量。您需要做的就是#include &lt;stdbool.h&gt; 走出“一切都是int”的时代。
  • 还有很多系统仍在使用 C89。
  • @BlueMoon 谢谢! flag的使用非常有帮助。
  • @BlueMoon,很多吗?不过只有一种。
【解决方案2】:

你可以这样做:

for (i = 0; i < 5; i++) {
    if (strstr(tracks[i], searchfor) {
        printf("\nMatch found\n);
        printf("Track[%n]: %s", i, tracks[i]);
        return;
    }
}
printf("\nNo matching tracks found!");

【讨论】:

    【解决方案3】:

    要适应变量类型,您可以使用定义

    #define TRACKS 5
    

    在包含之后...每当您想更改金额时,您只需将 5 更改为新值即可。

     void findTrack(char search_for[])
     {
        int i;
        int found = 0;
        for(i = 0; i < TRACKS; i++)
        {
           if(strstr(tracks[i], search_for))   
           {
               found = 1;
               printf("\n Match found\n");     
               printf("\n Track[%i]: %s\n", i, tracks[i]);     
               //break;
           }
        }
    
        if (!found)     printf("\n No matching tracks found!");
      }
    

    我已经评论了break,因为这取决于你想要做什么......如果你想只找到第一个包含该单词的曲目,你应该让break但是如果你想找到 所有 匹配,那么你不应该在找到第一个匹配后中断。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      相关资源
      最近更新 更多