【问题标题】:C -fscanf causing abort trap: 6 on EOFC -fscanf 导致中止陷阱:EOF 上为 6
【发布时间】:2015-01-26 11:39:30
【问题描述】:

我是 C 新手,编写了一个小程序,它从文件中读取大量推文,将主题标签存储在哈希表中,然后打印出出现频率最高的 10 个主题标签。

程序现在可以运行,但我收到了一个我不明白的错误,Abort trap: 6。

通过调试我已经确定它发生在线路上:

if (fscanf(src_file, "%s", current_word) == EOF){

在最后一次迭代中。使用打印,我已经看到文件的其余部分得到了正确处理,并且当上述行到达 EOF 时总是会发生这种情况。

解决此错误的方法是将我的 char current_word[] 变量的初始容量从 257 增加到 1000。但是,这远远大于我处理几乎每个单词所需的容量。谁能让我更深入地了解 fscanf() 在到达文件末尾时发生了什么以及为什么我显然需要为其分配更多空间?

快速说明:代码 sn-p 调用了此处未列出的函数,但它们在跟踪错误时已被删除,并且不会影响错误的行为。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "hashtable.h"
#include <ctype.h>

//NOTE: using 0 for all failiures and 1 for all success

int main(int argc, char **argv){
    //opens file via command line argument
    FILE *src_file = fopen(argv[1], "r");;
    if (src_file == NULL){
        fprintf(stderr, "There was an error opening the file.") ;
        return 0;
    }

    //define hashtable and malloc space
    hashtable* tweet_table = malloc(sizeof(hashtable));
    //read word by word and put any hashtags in hashtable
    char current_word[257];
    int looper = 1;
    while (looper == 1){
        if (fscanf(src_file, "%s", current_word) == EOF){
            looper = 0;
        }
        else if (current_word[0] == '#'){
            int i;
            for (i = 1; i < strlen(current_word); i+=1){
                current_word[i] = tolower(current_word[i]);
            }
            assert (put(current_word, tweet_table) == 1);
        }
    }

    //sorts and prints 10 most common tweets
    find_frequent(tweet_table);

    //close file when finished with operations
    fclose(src_file);
    printf("all good");

    return 1;
}

【问题讨论】:

  • 你可以试试这个if (fgets(current_word, sizeof(current_word), src_file) != NULL)吗?
  • 你不是一个接一个地阅读单词,你是一个接一个地阅读文件
  • 放开所有的looper逻辑,从while (fscanf(src_file, "%s", current_word) == 1)开始,虽然我一直相信code-unseen。
  • 如果字符串为char current_word[257];,请使用"%256s" 以防止字符串溢出其变量并造成严重破坏。

标签: c


【解决方案1】:

修改代码以防止对current_word @Jonathan Leffler 的阅读过多
代码可能仍需要使用大于 257 的值。

char current_word[257];
...
// if (fscanf(src_file, "%s", current_word) == EOF){
// 256 is the max input string length, 1 less that array size
if (fscanf(src_file, "%256s", current_word) == EOF) {

以下是其他建议的更改:

    // Only one ; needed
    // FILE *src_file = fopen(argv[1], "r");;
    FILE *src_file = fopen(argv[1], "r");

    // Consider this style: IMO less error prone and easier to maintain
    // hashtable* tweet_table = malloc(sizeof(hashtable));
    hashtable* tweet_table = malloc(sizeof *tweet_table);

    // Simplify
    //int looper = 1;
    //while (looper == 1){
    //    if (fscanf(src_file, "%s", current_word) == EOF){
    //     looper = 0;
    while (fscanf(src_file, "%256s", current_word) == 1) {

    // calculate length once, use size_t (although with limits like 257, int will do)
    // int i;
    // for (i = 1; i < strlen(current_word); i+=1){
    size_t len = strlen(current_word);
    size_t i;
    for (i = 1; i < len; i+=1) {

可以添加一个测试if (len == 256),那么可能你的缓冲区太小了。如果您想编写具有动态缓冲区大小的代码,则需要做更多的工作。检查您的系统是否有getline()

【讨论】:

  • 谢谢,这成功了。 looper 变量只是测试一些不同事物的保留。添加 %256s 就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-02
相关资源
最近更新 更多