代码不断崩溃(第4.2周已停止工作

时间:2015-05-18 16:35:01

标签: c arrays file fgets

我有一个程序必须从文件中获取最长的句子。 为了达到这个目的,我将第一个句子放在一个数组中,然后将未来的句子与当前最大的句子大小进行比较。

然而,比较两个阵列的行为使我无法理解。 数组的current_sentence和longest_sentence都是80个字符长,但我想知道哪个实际上包含最长的句子(最长可达80个字符)。

我已经尝试了很多不同的解决方案(通过谷歌,其中大部分是stackoverflow结果)但每次我尝试返回的值是文件中的第一句话,这让我相信检查本身完全失败,或者两个数组的长度都返回为80。

这些尝试包括(但不限于):

if((sizeof(current_sentence) / sizeof(char)) < (sizeof(longest_sentence) / sizeof(char))

if(sizeof(current_sentence) / sizeof(current_sentence[0])) < (sizeof(longest_sentence) / sizeof(longest_sentence[0]))

这是我的代码:

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

char *langste_regel(char *);

int main(void) {
    /*
     * stdout and stderr required for proper output
     */
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    char *s = langste_regel("vb1.txt");
    if(s != NULL) {
        printf("\nde langste regel is: %s\n", s);
        free(s);
    }

    return 0;
}

char *langste_regel(char *filename) {
    FILE *file;
    file = fopen(filename, "r");

    if(file == NULL) {
        fprintf(stderr, "Kan bestand niet %s openen", filename);
    }

    char current_sentence[80];
    int len = 2;
    char *longest_sentence = (char *)malloc(sizeof(char) * len);

    fgets(longest_sentence, 80, file);

    while(fgets(current_sentence, 80, file)) {
        if(sizeof(current_sentence) < sizeof(longest_sentence)) {
            strncpy(longest_sentence, current_sentence, 80);
        }
    }

    fclose(file);

    return longest_sentence;
}

3 个答案:

答案 0 :(得分:3)

您希望使用strlen()来获取行的长度,而不是sizeof,它返回对象占用的字节数。

更改

    if(sizeof(current_sentence) < sizeof(longest_sentence)) {

    if(strlen(current_sentence) < strlen(longest_sentence)) {

我看到的另一个问题是你只分配了2个字节,但在这里只能读取80个字节:

  char *longest_sentence = (char *)malloc(sizeof(char) * len);

  fgets(longest_sentence, 80, file);

答案 1 :(得分:1)

代码

sizeof(current_sentence)

没有按你的想法行事。要查找以空字符结尾的字符串的长度,请使用

strlen(current_sentence)

答案 2 :(得分:1)

您的代码存在许多问题。

  file = fopen(filename, "r");

   if(file == NULL) {
       fprintf(stderr, "Kan bestand niet %s openen", filename);
   }

您检查fopen()调用是否失败,但是您仍然继续使用file指针。您应该向呼叫者返回错误指示。

  char current_sentence[80];
  int len = 2;
  char *longest_sentence = (char *)malloc(sizeof(char) * len);

  fgets(longest_sentence, 80, file);

您将2个字节分配给longest_sentence,然后尝试将多达80个字节读入缓冲区。你应该分配80个字节。

如果您打算根据需要动态增长缓冲区,则需要更复杂的解决方案。你需要:

  • 尝试分配80个字节。
  • 尝试读取80个字节。
  • 检查字符串是否以换行符结束(\n)。
  • 如果没有,请尝试将realloc()缓冲区调整为更大的尺寸。
  • 继续阅读并重新分配,直到

    • 找到了换行符,或
    • 您已达到文件结尾或
    • 发生读取错误,或
    • 重新分配失败,或
    • 达到预定义的最大长度。

您也不会检查字符串是否已成功读取。 fgets()函数将在文件结尾返回NULL,或者如果发生读取错误。您应该向调用者返回错误指示符。例如:

if (!fgets(longest_sentence, 80, file)) {
  free (longest_sentence);
  return NULL:
}
  while(fgets(current_sentence, 80, file)) {
      if(sizeof(current_sentence) < sizeof(longest_sentence)) {
          strncpy(longest_sentence, current_sentence, 80);
      }
  }

sizeof运算符的结果是操作数的类型的大小,而不是字符串的长度。您应该使用strlen()(并反转比较,正如您在其他地方所述)。

while(fgets(current_sentence, 80, file)) {
    if(strlen(current_sentence) > strlen(longest_sentence)) {
        strncpy(longest_sentence, current_sentence, 80);
    }
}

使用strncpy()通常是有问题的。无论current_sentence的长度如何,上面的调用总是写入80个字节。通常,如果在输入字符串的前80个字节内未找到零,则将输出字符串置零。然而,它将在 this 的情况下,因为fgets()保证在这80个字符中有一个零字节。

简单的strcpy()在这里会更直接(在我看来)。