【问题标题】:C Text Processing: Output Wrong SizeC 文本处理:输出错误大小
【发布时间】:2014-10-02 01:12:27
【问题描述】:

我正在编写一个 ac 程序,它接受一个单词的文本文件,并且只复制没有大写或标点符号的单词,并且长度为 4 个或更多字符。我已经测试了布尔函数 int containsPunctuationOrCaps(char *word) 和 int longThanThree(char *word) ,它们都可以工作。但是,我的 main 函数只打印至少七个字符的单词,任何更长的单词都会被截断。

int main() {
  char *currentWord = malloc(36);
  int count = 0;
  char *Words[3000];
  FILE *fin, *fout;

  fin = fopen(INFILE,"r");
  if (fin==NULL) {
    printf("INPUT FILE NOT FOUND\n");
    return 1;
  } 
  while(fgets(currentWord, sizeof(currentWord), fin) != NULL) {
    if(!containsPunctuationOrCaps(currentWord) && longerThanThree(currentWord)) {
    Words[count]=currentWord;
    printf("%s\n",currentWord);
    count++;
    }
  }
  fclose(fin);    
}

当我改变 char *currentWord = malloc(36); 到 char currentWord[]; 它什么也不读。我该如何完成这项工作?

【问题讨论】:

  • sizeof(currentWord)sizeof(char *) 在你的机器上恰好是 8。
  • 谢谢你,你是对的。但是为什么它不接受较小的输入呢?

标签: c arrays text


【解决方案1】:

您将currentWord 声明为char *,它指向动态分配的内存。 sizeof 在编译时评估,并评估为 type of currentWord 所需的大小(以字节为单位) - 在您的情况下,存储内存地址/指针所需的大小,这显然是您系统上的 8 个字节。由于fgets 附加了一个终止\0 字节,所以fgets 调用仅读取7 个字符。

您可以用char currentWord[36]; 替换char *currentWord = malloc(36);(注意:您永远不会free 分配的内存),这将导致至少35 个字符被读取。但是,fgets 总是尝试读取直到行尾(或直到缓冲区已满),因此currentWord 数组将包含多个单词。

您可以在空格处拆分currentWord,但这需要在缓冲区末尾进行额外的检查逻辑(currentWord 的结尾是单词/行的结尾,还是缓冲区刚刚满并且话继续吗?)。完成您想要的最简单的方法可能是逐字符读取文件(使用getc,但您应该确保使用缓冲I/O,请参阅setbuf)。在阅读每个字符时,检查它是单词还是非单词字符(或 EOF)。在前一种情况下,您附加到缓冲区,而在后一种情况下,如果它符合您的条件,则输出该单词,但首先附加一个\0 终止符。 currentWord 缓冲区应该是动态分配的(除非您知道字长的明确上限),如果当前正在读取的字长超过分配的内存可以容纳的长度,您可能必须重新分配它。

【讨论】:

  • 谢谢;我没有意识到 sizeof() 在编译时进行了评估。现在我有一个不同的问题:我更改为 currentWord[36],现在它什么也读不出来。顺便说一下,这个单词列表是用换行符而不是空格分隔的。
  • 什么意思,什么都不打印?缓冲区是空的,还是每个单词都被您的 if 条件过滤掉了?另请注意fgets 将行终止字符添加到缓冲区!顺便说一句,Words[count]=currentWord; 行不会按预期工作 - 它仅将局部数组变量currentWord 的地址存储在Words 数组中,该地址对于每一行都是相同的,并且在每次迭代中都被覆盖。 Words[count] = strdup(currentWord) 应该可以工作(请注意,这会分配内存,以后应该是freed)。
  • 你是对的;是我的标点符号过滤器失败了,因为它计算了换行符。
【解决方案2】:

当你写作时

char currentWord[];

而不是

char *currentWord = malloc(36);

您声明了一个大小为 0 的静态字符数组。当 sizeof 应用于静态数组的名称时,结果是该数组的大小(以字节为单位)。

例如,在这种情况下:

char currentWord[10]; 

sizeof 会返回 10*sizeof(char)。

在您的情况下,数组为空,因此 sizeof(currentWord) 将返回 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多