首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C程序读取文本文件时的切分错误

C程序读取文本文件时的切分错误
EN

Stack Overflow用户
提问于 2016-11-11 16:43:05
回答 1查看 41关注 0票数 1

我想用这种格式(word:defn)从文本文件中打印一串单词及其定义。但是,在服务器上使用gcc运行程序时,我遇到了一个分段错误。奇怪的是,当我在本地桌面上编译C程序时,程序工作得很完美。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int read_dict() {
    FILE *fp;
    int c;
    char word[50];
    char defn[500];
    int sep = 0;
    int doublenew = 0;
    int i = 0;

    fp = fopen("textfile.txt", "r");
    if (fp == NULL) {
        perror("Error in opening file");
        return (-1);
    }

    while ((c = fgetc(fp)) != EOF) {
        if (feof(fp)) {
            break;
        }
        if (c == '.' && sep == 0) {
            sep = 1;
            word[i] = '\0';
            //c = fgetc(fp);
            i = 0;
        } else
        if (doublenew == 1 && c == '\n' && sep == 1) {
            defn[i] = c;
            i++;
            defn[i] = '\0';
            printf("%s %s", word, defn);
            i = 0;
            sep = 0;
            doublenew = 0;
        } else
        if (c == '\n' && sep == 1) {
            defn[i] = c;
            doublenew = 1;
            i++;
        } else
        if (sep == 0) {
            word[i] = c;
            i++;
        } else
        if (sep == 1) {
            defn[i] = c;
            i++;
            doublenew = 0;
        }
    }
    fclose(fp);
    return 0;
}

文本文件:

饼干。是一种小的,平的,甜的,烤好的,通常含有面粉,鸡蛋,糖,或者黄油,食用油或者其他的油或脂肪。它可能包括其他成分,如葡萄干,燕麦,巧克力片或坚果。 冰淇淋。是一种加糖的冷冻食品,通常作为零食或甜点食用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-11 17:03:32

单词长度限制为49个字符,定义为499个字符,但您从不检查代码中是否溢出。如果与您的示例不同,服务器上使用的字典有更长的单词和/或定义,则代码会调用未定义的行为,从而导致分段错误。

未定义的行为也可能不会导致任何可见的效果,就像本地机器上的情况一样。由于版本不同或命令行选项不同,由本地编译器生成的代码可能与服务器的代码不同。

检查数组边界以避免这种情况:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int read_dict() {
    FILE *fp;
    int c;
    char word[50];
    char defn[500];
    int sep = 0;
    int doublenew = 0;
    size_t i = 0;

    fp = fopen("textfile.txt", "r");
    if (fp == NULL) {
        perror("Error in opening file");
        return (-1);
    }

    while ((c = fgetc(fp)) != EOF) {
        if (feof(fp)) {
            break;
        }
        if (c == '\r') {
            /* ignore CR characters inserted by Windows before LF */
            continue;
        }
        if (c == '.' && sep == 0) {
            sep = 1;
            word[i] = '\0';
            //c = fgetc(fp);
            i = 0;
        } else
        if (doublenew == 1 && c == '\n' && sep == 1) {
            if (i < sizeof(defn) - 1) {
                defn[i] = c;
                i++;
            }
            defn[i] = '\0';
            printf("%s %s", word, defn);
            i = 0;
            sep = 0;
            doublenew = 0;
        } else
        if (c == '\n' && sep == 1) {
            if (i < sizeof(defn) - 1) {
                defn[i] = c;
                i++;
            }
            doublenew = 1;
        } else
        if (sep == 0) {
            if (i < sizeof(word) - 1) {
                word[i] = c;
                i++;
            }
        } else
        if (sep == 1) {
            if (i < sizeof(defn) - 1) {
                defn[i] = c;
                i++;
            }
            doublenew = 0;
        }
    }
    fclose(fp);
    return 0;
}

注意:如果服务器上没有打印任何内容,这意味着文件没有两个连续的换行符'\n'。如果您在系统和服务器上使用相同的文件,如果您在系统上使用Windows,在服务器上使用Linux,程序在行尾使用的'\r'字符上的行为将有所不同。您必须显式地忽略这些字符,因为它们仅在Windows上被隐式忽略,而不是在Linux上被忽略。我修改了上面的代码来解释这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40552483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档