正如标题所示,我得到了分段错误(核心转储)输出。我已经使用了调试器,但我不知道它为什么这样做。我对 C 有点陌生,所以我们将不胜感激。
该程序应该:
读取问题:它从输入中读取一组调查问题并将其分类为“直接”或“反向”。 读取响应:它处理调查响应(例如,“完全不同意”、“同意”等),将其转换为数值,并为每个受访者存储它们。 计算频率:它计算并打印每个问题的回答频率。如果问题被标记为“反向”,则答案会相应调整(例如,反向评分)。 计算分数:它根据每个受访者对调查的回答计算并打印不同类别(例如,信心、兴趣、性别、有用性、专业性)的分数。
`#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXR 100
#define MAXQ 50
//define constants for the questions
#define DIRECT 0
#define REVERSE 1
//the arrays to hold the questions
char questions[MAXQ][256];
int q_type[MAXQ]; //0 for direct 1 for reverse
int responses[MAXR][MAXQ]; //array to hold the responses
//function to read the questions
void readquestions(){
char buffer[4096];
//reading questiosn from input
if(fgets(buffer, sizeof(buffer), stdin) != NULL){
char *token = strtok(buffer, ";");
int i = 0;
while (token != NULL && i < MAXQ){
strcpy(questions[i], token);
token = strtok(NULL, ";");
i++;
}
}
//reads question type
if(fgets(buffer, sizeof(buffer), stdin) != NULL){
char *token = strtok(buffer, ";");
int i = 0;
while(token != NULL && i < MAXQ){
if(strcmp(token, "Reverse") == 0){
q_type[i] = REVERSE;
}else{
q_type[i] = DIRECT;
}
token = strtok(NULL, ";");
i++;
}
}
/*//for loop that counts how many questions are read
for(int i = 0; i < MAXQ; i++){
q_type[i] = 0; // initialize as not REVERSE
snprintf(questions[i], 256, "Questions %d", i + 1);
}*/
}
//function to read responses
void readresponses(int *num_respondents){
char buffer[4096]; //holds each line of responses
*num_respondents = 0;
//for loop to process responses
while(fgets(buffer, sizeof(buffer), stdin) != NULL){
if(buffer[0] == '#') continue; //skip comment lines
char *token = strtok(buffer, ",");
//skip demographic fields
for(int i = 0; i < 3; i++){
if(token == NULL) break;
token = strtok(NULL, ",");
}
if(token == NULL){
continue;
} //skips if there are no responses
//parse respones
for(int i = 0; i < MAXQ; i++){
if(token == NULL) break;
if(strcmp(token, "fully disagree") == 0){
responses[*num_respondents][i] = 1;
}else if(strcmp(token, "disagree") == 0){
responses[*num_respondents][i] = 2;
}else if(strcmp(token, "partially disagree") == 0) {
responses[*num_respondents][i] = 3;
}else if(strcmp(token, "partially agree") == 0) {
responses[*num_respondents][i] = 4;
}else if(strcmp(token, "agree") == 0) {
responses[*num_respondents][i] = 5;
}else if(strcmp(token, "fully agree") == 0) {
responses[*num_respondents][i] = 6;
}
token = strtok(NULL, ","); //move to next response
}
(*num_respondents)++;
}
}
//this function calculates the frequencies
void calculatefrequencies(int num_questions, int num_respondents){
//simple if statement to return function if theres no respondents
if(num_respondents == 0){
printf("No respondents to calculate frequencies\n");
return;
}
printf("FREQUENCIES ARE COMPUTED FOR EACH LEVEL OF AGREEMENT BELOW\n\n");
for(int i = 0; i < num_questions; i++){
int freq[6] = {0}; // freq. for the 6 likert levels
//for loop to count the freq .of each response
for(int j = 0; j < num_respondents; j++){
int response = responses[j][i];
if(q_type[i] == REVERSE){//if reverse-scored
response = 7 - response;
}//this reverses the score if its a reverse question
freq[response - 1]++;
}
//to print relative frequencies
printf("%s\n", questions[i]);
for(int z = 0; z < 6; z++){
double percent = (num_respondents > 0) ? (freq[z] * 100.0) / num_respondents : 0.0;
printf("%.2f: %s\n", percent, (z == 0) ? "fully disagree" :
(z == 1) ? "disagree" :
(z == 2) ? "partially disagree" :
(z == 3) ? "partially agree" :
(z == 4) ? "agree" : "fully agree");
}
printf("\n");
}
}
//function to calculate and print scores for each respondent
void calculatescores(int num_questions, int num_respondents){
if(num_respondents == 0){
return;
}
printf("SCORES FOR ALL THE RESPONDENT\n");
//looping through each respondent and to compute scores
for (int r = 0; r < num_respondents; r++){
int total_c = 0, total_i = 0, total_g = 0, total_u = 0, total_p = 0;
for(int q = 0; q < num_questions; q++){
int score = responses[r][q];
if(q_type[q] == REVERSE){
score = 7 - score; //reverse the score if needed
}
//categorization
if (q < 8) total_c += score; // Confidence
else if (q < 18) total_i += score; // Interest
else if (q < 28) total_g += score; // Gender
else if (q < 34) total_u += score; // Usefulness
else total_p += score; // Professionalism
}
printf("C:%d, I:%d, G:%d, U:%d, P:%d\n", total_c, total_i, total_g, total_u, total_p);
}
}
int main() {
int num_questions = 0;
int num_respondents = 0;
readquestions(); //read question from input
//for loop to count how many questions are read
for(int i = 0; i < MAXQ; i++){
if(questions[i][0] != '\0'){
num_questions++;
}
}
readresponses(&num_respondents); //read responses from input
calculatefrequencies(num_questions, num_respondents); //calculate frequencies
calculatescores(num_questions, num_respondents); //calculate scores
//checks for debugging
//printf("Number of questions: %d\n", num_questions);
//printf("Number of respondents: %d\n", num_respondents);
return 0;
}
`
代码至少存在这些问题:
fgets()
保存 '\n'
if(strcmp(token,...
树都会失败,因为 token
可能有 '\n'
。 请参阅从 fgets() 输入中删除尾随换行符。潜在的缓冲区溢出
strcpy(questions[i], token);
有溢出的风险questions[i]
。
简单的替代方案:
sprintf(questions[i], sizeof questions[i], token, "%s", token);
。也许还有其他问题