我想用这种格式(word:defn)从一个文本文件中打印一堆单词及其定义但是,在服务器上使用gcc运行程序时,我遇到了一个分段错误。奇怪的是,当我在本地桌面上编译C程序时,程序运行得很好。
#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;
}
文本文件:
饼干。是一种小的,平的,甜的,烘焙好的,通常含有面粉,鸡蛋,糖,或者黄油,食用油或者其他油或脂肪。它可能包括其他成分,如葡萄干、燕麦、巧克力片或坚果。
冰淇淋。是一种甜的冷冻食品,通常作为零食或甜点食用。
最佳答案
单词长度限制为49个字符,定义限制为499个字符,但您从不检查代码中是否存在溢出。如果与您的示例不同,服务器上使用的字典有较长的单词和/或定义,则您的代码将调用未定义的行为,这可能会导致分段错误。
未定义的行为也可能不会造成任何可见的影响,就像您的本地计算机上的情况一样。由于版本不同或命令行选项不同,本地编译器生成的代码和服务器生成的代码可能不同。
检查数组边界以避免:
#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,则程序的行为在Windows用于行尾的'\r'
字符上会有所不同。必须显式忽略这些字符,因为它们仅在Windows上隐式忽略,而在Linux上不隐式忽略。我修改了上面的代码来解释这个问题。关于c - 读取文本文件时C程序中的段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40552483/