【问题标题】:C histogram of words printing problems文字打印问题的C直方图
【发布时间】:2015-06-24 10:57:51
【问题描述】:

我有这段代码,我想要它做的是打印代表单词的字符串,并打印它在文件中出现的次数,而不是打印出类似这样的内容:(大量空白)和然后这个号码-1076720020,我不知道它是从哪里来的,我该如何解决这个问题?

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


struct podatki {
    char beseda[1000];
    int frekvenca;
};

void zamenjaj(char *str1, char *str2) {
   char *beseda2 = (char *)malloc((strlen(str1) + 1) * sizeof(char));
   strcpy(beseda2, str1);
   strcpy(str1, str2);
   strcpy(str2, beseda2);
   free(beseda2);
} 


int posodobi(struct podatki s[], const char unit[], int count) {
    int i =0;

    for (i = 0; i < count; i++) {
        if (strcmp(s[i].beseda, unit) == 0) {
            s[i].frekvenca++;
            return count;
        }
    }
    strcpy(s[count].beseda, unit);
    s[count].frekvenca++;
    return (count + 1);
}




int main() {
    int stBes;
    scanf("%d", &stBes);
    //zacetne deklaracije
    struct podatki s[1000];
    char string[1000], unit[2000], c;
    int i = 0;
    int frekvenca = 0; 
    int j = 0; 
    int count = 0;
    int num = 0;
    //branje 
    for (i = 0; i < 1000; i++) {
       s[i].frekvenca = 0;
    }

    i = 0;
    do {
       fflush(stdin);
       c = getchar();
       string[i++] = c;
    } while (c != '\n');


   //pretvori v majhne crke
   char *p;
   for (p = string; *p != '\0'; ++p) {
        *p = tolower(*p);
   }

   string[i - 1] = '\0';

   for (i = 0; i < strlen(string); i++) {
        while (i < strlen(string) && string[i] != ' ' &&  !ispunct(string[i])) {
       unit[j++] = string[i++];
    }
    if (j != 0) {
        unit[j] = '\0';
        count = posodobi(s, unit, count);
        j = 0;
    }
}

int a;
for (i = 0; i < count; ++i) {
    for (j = i + 1; j < count; ++j) {
        if (s[i].frekvenca < s[j].frekvenca) {
            a =  s[i].frekvenca;
            s[i].frekvenca = s[j].frekvenca;
            s[j].frekvenca = a;
            zamenjaj(s[i].beseda, s[j].beseda);

        }
    }
}

for (i = 0; i < count; i++) {
    for (j = 1; j < count; j++) {
        if (s[i].frekvenca == s[j].frekvenca){
            if (strcmp(s[i].beseda, s[j].beseda) < 0) {
                a =  s[i].frekvenca;
                s[i].frekvenca = s[j].frekvenca;
                s[j].frekvenca = a;
                zamenjaj(s[i].beseda, s[j].beseda);
            }
        }
    }
}

//printanje
for (i = 0; i < stBes; i++) {
    printf("%s\t   %d\n", s[i].beseda, s[i].beseda);
    if (s[i].frekvenca > 1) {
        num++;
    }
}
return 0;

}

【问题讨论】:

  • 第一个问题fflush(stdin); -> 未定义的行为。而这个while (i &lt; strlen(string) 是一件非常糟糕的事情,因为strlen() 计算字符串的长度,所以你正在执行一个多次给出相同结果的操作。
  • 您的堆栈超过 100 万字节,在 Windows 上默认堆栈大小为 1 MB,因此如果您在 Windows 上,您将危险地接近堆栈的限制。
  • 我还看到你经常使用结构中的beseda 数组,在我看来,有些情况下你在数组初始化之前就使用了它。这当然会导致未定义的行为。
  • 并且要真正找到问题的根源,您应该真正在调试器中运行程序,并逐行检查它是否符合您的预期它去做。

标签: c printing histogram


【解决方案1】:

问题是您在nul 终止它之前将字符串转换为小写。

这里

i = 0;
do {
   fflush(stdin);
   c = getchar();
   string[i++] = c;
} while (c != '\n');
/* Goes here            <---------------------+ */
                      /*                      | */
//pretvori v majhne crke                      | */
char *p;              /*                      | */
for (p = string; *p != '\0'; ++p) {/*         | */
     *p = tolower(*p);/*                      | */
}                     /*                      | */
                      /*                      | */
string[i - 1] = '\0'; /* ---------------------+ */

您还应该删除fflush(stdin),而是使用getchar() 来获取之前scanf() 忽略的空白字符,请正确使用scanf() 并检查它的返回值。

【讨论】:

  • 因为正如@JoachimPileborg 所说,你正在溢出堆栈,为什么你的缓冲区这么大?你认为记忆没有限制吗?
猜你喜欢
  • 2014-12-08
  • 2016-02-03
  • 2013-09-26
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多