所以我刚刚完成了一个学校计划。它编译并运行罚款,直到执行最后一行。我得到了所有正确的输出,我希望只是无法弄清楚我正在做什么导致这个段错误。对不起,如果这是一个重复的问题。我看到很多seg故障问题,但是看不到比较,因为他们中的大多数人都说了很长的引用空指针的行,但我很自信我的指针不是空的。
下面是代码:对不起,我只想给那些希望帮助有机会扫描代码的人,看看他们是否看到了FILE *的任何问题。谢谢。
版主:如果有更好的方法来分享这段代码,请告诉我。上次我分享了指向第三方网站的链接,并将其删除。
大约250行。
//Includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Constants
#define NUM_OF_CANDIDATES 7
#define INPUT_FILE_NAME "elections.txt"
#define NUM_OF_VOTES 117
//Stuctures
/**
* Represents data connected to a candidate. Stores total votes and a name up to
* 20 letters(inclusive).
*/
typedef struct candidate
{
char name[21];
int votes;
} Candidate;
//Method Prototypes
int Initialize(Candidate*, int, FILE*);
int ProcessVotes(Candidate*, int, int, FILE*);
void printResults(Candidate*, int, int);
/**
* Method: int main()
*
* Summary: Entry point to program
*
* @return
* EXIT_FAILURE - Some error occurred
* EXIT_SUCCESS - No errors
*/
int main()
{
//Instantiate array of Candidate
Candidate electionCandidates[NUM_OF_CANDIDATES];
//Open input file
FILE* fin = fopen(INPUT_FILE_NAME, "r");
if(fin == NULL)
{
printf("Unable to open file %s\n", INPUT_FILE_NAME);
return EXIT_FAILURE;
}
//Initialize candidates
if( Initialize(electionCandidates, NUM_OF_CANDIDATES, fin) )
{
printf("Failed to initialize candidates.\n");
fclose(fin);
return EXIT_FAILURE;
}
//Process the votes
if(ProcessVotes(electionCandidates, NUM_OF_CANDIDATES, NUM_OF_VOTES, fin ))
{
printf("Failed to process votes\n");
fclose(fin);
return EXIT_FAILURE;
}
//Print results
printResults(electionCandidates, NUM_OF_CANDIDATES, NUM_OF_VOTES );
//Clean up
fclose(fin);
return EXIT_SUCCESS;
}
/**
* Method: int Intialize(Candidate* arr, int numOfCandidates, FILE* fin)
*
* Summary:
*
* Initializes the Candidates in arr. Reads input from fin
*
* @param arr - pointer to array of Candidate
* @param numOfCandidates - number of candidates in arr
* @param fin - input file holding initial date
*
* @return
* 0 - Success
* 1 - Failed to Initialize
*/
int Initialize(Candidate* arr, int numOfCandidates, FILE* fin)
{
char buf[21] = {'\0'};
char* c;
//Loop through all Candidate
int i = 0;
for(i = 0; i < numOfCandidates; i++)
{
//fscanf fails to read a string
if( fgets(buf, 20, fin) == NULL || feof(fin) )
{
return 1;
}
//Remove new line char from buffer stream
c = strrchr(buf, '\n');
*c = '\0';
//Copy name from buffer to voter's struct
strcpy((arr+i)->name, buf);
//INitialize votes to 0
(arr+i)->votes = 0;
}
return 0;
}
/**
* Method: int ProcessVotes(Candidate* arr, int numOfCandidates, int numOfVotes, FILE* fin)
*
* Summary:
*
* Counts votes corresponding to the candidates in arr from the input file
*
* @param arr - pointer to array of Candidate
* @param numOfCandidates - number of Candidate in arr
* @param numOfVotes - number of votes to process
* @param fin - input file to read data from
* @return
* 0 - Process Success
* 1 - Failure to process votes
*/
int ProcessVotes(Candidate* arr, int numOfCandidates, int numOfVotes, FILE* fin)
{
int i = 0, curVote = 0, idx = 0;
for( i = 0; i < numOfVotes; i++ )
{
if(feof(fin) || fscanf(fin, "%d", &curVote ) == 0 )
{
return 1;
}
//Valid votes corresponding to candidates are 1<= curVote <= numOfCanidates
//Indexes corresponding to the current vote will be ( curVote - 1 )
idx = curVote - 1;
if( idx / numOfCandidates == 0)
{
(arr+idx)->votes++;
}
}
return 0;
}
/**
* Method: void printResults( Candidate* arr, int numOfCandidates, int numOfVotes )
*
* Summary:
*
* Displays the results out to stdin. First finds the winners as well
* as updating spoiled votes. Then displays winners and spoiled votes
*
* @param arr - pointer to array of Candidate
* @param numOfCandidates - numberOfCandidates in arr
* @param numOfVotes - number of Votes processed
*/
void printResults( Candidate* arr, int numOfCandidates, int numOfVotes )
{
// Holds Candidate* to reference the winners
Candidate** winners = (Candidate**)malloc(sizeof(Candidate*)*numOfCandidates);
*winners = arr; //assume first Candidate is the only winner
int numOfWinners = 1;
//counter for spoiled votes. max number of spoiled votes is numOfVotes
//subtract first candidate's votes because we will start our loop
//with the second candidate
int spoiledVotes = numOfVotes - arr->votes; //subtract first Candidate votes
int i = 0;
for(i = 1; i < numOfCandidates; i++)
{
if( (arr+i)->votes > (*winners)->votes )
{
//Single winner at this point re-initialize list and counter
*winners = arr + i;
numOfWinners = 1;
}
else if ((arr + i )->votes == (*winners)->votes )
{
//add a winner to winner list
*(winners + numOfWinners) == (arr+i);
numOfWinners++;
}
//update spoiled votes
spoiledVotes -= (arr+i)->votes;
}
//Tie
if(numOfWinners > 1)
{
printf("There is a tie between %s ", (*winners)->name);
for( i = 1; i < numOfWinners; i++)
{
printf("and %s ", (*winners + i)->name );
}
printf("who got a total of %d votes each.\n", (*winners)->votes);
}
//No tie
else
{
printf("%s won the election with %d votes.\n",
(*winners)->name, (*winners)->votes );
}
printf("There was a total of %d spoilt votes.\n", spoiledVotes);
//Clean up
free(winners);
}
答案 0 :(得分:1)
编译警告
*(winners + numOfWinners) == (arr+i);
应该是:
*(winners + numOfWinners) = (arr+i);
答案 1 :(得分:1)
在ProcessVotes
中,您有:
idx = curVote - 1;
if( idx / numOfCandidates == 0)
{
(arr+idx)->votes++;
}
但是,您没有代码可以验证curVote
从fscanf()
扫描后是否为正数。这意味着如果curVote
小于或等于0,则在arr
上使用负索引,这将损坏内存(并导致未定义的行为)。