【问题标题】:Why do I get such a messed up output?为什么我会得到如此混乱的输出?
【发布时间】:2015-05-10 06:26:26
【问题描述】:

我正在编写一个程序来打印出现的字母和(一个、两个、三个字母等)单词。到目前为止,我已经让字母部分正常工作,但我根本无法让单词部分工作,更不用说区分一个、两个或三个字母的单词了。我试图找出程序在哪里搞砸了,似乎是在我尝试将它们存储在数组“word”中。

有人建议使用 strlok(),但没有提及如何。

编辑:我用 sizeof() 替换了 strlen() 并设置了我的 'i' 变量 = 0 它应该在的位置,但我的输出仍然是整个字符串的第一个字母和一些奇怪的字符。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
void findLetters(char *ptr);
void findWords(char *point);


int main()
{
    char textStream[100]; //up to 98 characters and '\n\ and '\0'

    printf ( "enter some text\n");
    if ( fgets( textStream, sizeof ( textStream), stdin)) //input up to 99 characters
    {
        findLetters(textStream);
    }
    else
    {
        printf ( "fgets failed\n");
    }
    findWords(textStream);
    return 0;
}

void findLetters(char *ptr) //find occurences of all letters
{
    int upLetters[26];
    int loLetters[26];
    int i;
    int index;

    for ( i = 0; i < 26; i++) // set array to all zero
    {
        upLetters[i] = 0;
        loLetters[i] = 0;
    }
    i = 0;
    while ( ptr[i] != '\0') // loop until prt[i] is '\0'
    {
        if (ptr[i] >= 'A' && ptr[i] <= 'Z') //stores occurrences of uppercase letters
        {
            index = ptr[i] - 'A';// subtract 'A' to get index 0-25
            upLetters[index]++;//add one
        }

        if (ptr[i] >= 'a' && ptr[i] <= 'z') //stores occurrences of lowercase letters
        {
            index = ptr[i] - 'a';//subtract 'a' to get index 0-25
            loLetters[index]++;//add one
        }
        i++;//next character in ptr
    }
    printf("Number of Occurrences of Uppercase letters\n\n");
    for ( i = 0; i < 26; i++)//loop through 0 to 25
    {
        if ( upLetters[i] > 0)
        {
            printf("%c : \t%d\n", (char)(i + 'A'), upLetters[i]);
            // add 'A' to go from an index back to a character
        }
    }
    printf("\n");
    printf("Number of Occurrences of Lowercase letters\n\n");
    for ( i = 0; i < 26; i++)
    {
        if ( loLetters[i] > 0)
        {
            printf("%c : \t%d\n", (char)(i + 'a'), loLetters[i]);
            // add 'a' to go back from an index to a character
        }
    }
}

void findWords(char *point)
{
    int i = 0; 
    int k = 0; 
    int count = 0;
    int j = 0; 
    int space = 0;
    int c = 0;
    char word[50][100], word1[50][100];

    for (;i < sizeof(point);i++) //counts # of spaces between words
    {
        if ((point[i] == ' ')||(point[i] == ',')||(point[i] == '.'))
        {
            space++;
        }
    }
    i = 0; 
    for(; i < sizeof(point); i++) //seperates strings from each other
    {
        if(point[i] == '.' || point[i] == 44|| point[i] == 46)
        {
            word[j][k] = '\0';
            j++;
            k = 0;
            printf("%s\n",point[i]);
        }
        else
        {
            word[j][k] = point[i];
            k++;
        }
        printf("%s\n",word[j]);
    }
    k = 0;

    for (i = 0;i <= space;i++) 
    {
        for (j = 0;j <= space;j++) 
        {
            if (i == j) // finds occurrences of words
            {
                strcpy(word1[k], word[i]); //copies words in new array
                k++;
                count++;

            } 
            else if(strcmp(word1[j], word[i]) != 0) //makes sure that the word copied equals the word from the string
            {
                ;
            }
        }
    }
    j = 0;
    i = 0;
    for (;i < count ;i++) 
    {
        for (;j <= space;j++)
        {
            if (strcmp(word1[i], word[j]) == 0) //counts occurrence of each word
            {
                c++;
            }
        }
        printf("%s \t %d times\n", word1[i], c);
        c = 0;
    }
}

【问题讨论】:

  • 如果您描述了“搞砸”的意思,那会有所帮助。你的输入是什么,你得到了什么输出,你期望什么?
  • char *word = strtok(point," ,."); 返回每​​个单词。在strtok 之后使用此循环:while(word != NULL){ printf("Word:%s\n",word); word = strtok(NULL," ,."); }
  • 很明显,如果fgets() 失败,你不应该像findLetters() 那样做findWords()。但是,这不太可能是您的主要问题。
  • 感谢您的建议,我会看看这些是否有帮助。混乱的输出只是输入的字符串中的第一个字母和一些奇怪的字符。
  • 不要更改问题以合并答案,这会使问题和答案看起来毫无意义。

标签: c arrays loops words


【解决方案1】:

你的代码有几个问题:

  • for(;i &lt; strlen(point); i++) //seperates strings from each other 执行此行时,i 的值已经是strlen,因此不会执行以下for。添加i=0 进行修复。

  • 你应该使用sizeof而不是strlen,否则你会错过最后一个字。

  • if(point[i] == '.' || point[i] == 44|| point[i] == 46) 你没有在这里检查' '。正确的 if 条件应该是: if(point[i] == ' ' || point[i] == '.'|| point[i] == ' ')

  • 您的代码没有考虑逗号和空格一起出现的情况。

  • 您用于在数组中查找单词的算法存在缺陷。 你应该使用这样的东西:

how_many_times(word[i], word, number_of_words);

int how_many_times(char * word, char words[50][100], int how_many_words) {
  int i = 0, counter=0;                                                                         
  for (i=0; i< how_many_words; i++) {
    if ( strcmp(words[i], word) == 0 ) {
      counter++;
    }
  } 
  return counter;
}    

【讨论】:

  • 如果你想在列表中缩进代码,使用 8 个空格。否则,使用 4
【解决方案2】:

一个主要问题是你的第二个循环没有运行:

    int i=0;
    for (;i < strlen(point);i++) //counts # of spaces between words
    {
      ...
    }

    for(;i < strlen(point); i++) //seperates strings from each other
    {
      ...
    }

i 在第二个 for 循环开始时仍然是 strlen(point)-1,因此不会运行。我建议始终在 for 循环中指定起点,并且只计算一次字符串长度,而不是每个循环。

int len = strlen(point);
for (i=0; i < len; i++)

【讨论】:

  • 除非您修改point 中的字符串长度,否则使用for (i = 0; i &lt; strlen(point); i++) 是个坏主意,因为它将循环从O(N) 转换为O(N^2),其中N 是字符串的长度,使循环成为二次算法。
  • 为什么会有不同?
  • @Sosa 你问的是我的回答还是乔纳森的评论?
  • @weston Jonathan 的评论正是我要问的;我明白你的回答。
  • 你应该使用@和他们的名字来引起他们的注意,否则他不会知道你回复了他。他是说因为strlen 是用循环实现的,所以就目前而言,您有嵌套循环,它们以二次时间运行。对于长度为 10 的字符串,时间为 100,对于长度为 20 的字符串,时间为 400,而不是两倍。
猜你喜欢
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2016-05-13
  • 2022-11-25
  • 2023-01-08
  • 2018-12-21
  • 2012-10-11
  • 1970-01-01
相关资源
最近更新 更多