Arrays 有没有办法在C中存储一个数组,其中的值在不同的索引处循环?
我正在用C语言创建一个Hangman项目,其中要猜测的单词由破折号表示,随着游戏的进行,破折号将被正确的猜测所取代。我用一个链表来存储所有的单词。我已经弄清楚了几乎所有的功能,但是,我的最新版本的游戏运行得非常完美,除非单词中有一个重复出现的角色需要猜测。之所以会出现这种情况,是因为我创建了一个函数,该函数可以从用户那里进行猜测,并将其与秘密字进行比较。如果对“secret”字符串的特定索引的猜测是正确的,它会将破折号字符数组的索引设置为相同的猜测(并显示破折号供玩家猜测)。问题在于破折号字符串是一个数组,如果一个字符出现两次,就会弄乱破折号的长度 我不知道接下来该怎么办。有没有办法在两个不同的索引中存储循环值,或者我应该尝试另一种方法来存储字符串?此外,如果问题令人困惑,阅读程序并稍微理解代码可能会有所帮助。我在每个函数中都用注释对其进行了格式化,所以即使我的代码有点凌乱,也不难理解。非常感谢您的帮助Arrays 有没有办法在C中存储一个数组,其中的值在不同的索引处循环?,arrays,c,linked-list,Arrays,C,Linked List,我正在用C语言创建一个Hangman项目,其中要猜测的单词由破折号表示,随着游戏的进行,破折号将被正确的猜测所取代。我用一个链表来存储所有的单词。我已经弄清楚了几乎所有的功能,但是,我的最新版本的游戏运行得非常完美,除非单词中有一个重复出现的角色需要猜测。之所以会出现这种情况,是因为我创建了一个函数,该函数可以从用户那里进行猜测,并将其与秘密字进行比较。如果对“secret”字符串的特定索引的猜测是正确的,它会将破折号字符数组的索引设置为相同的猜测(并显示破折号供玩家猜测)。问题在于破折号字符串
#包括
#包括
#包括
#包括
int nodeNum、机会、失误、得分、猜测;
字符*秘密;
字符incorrGuess[50],guess,破折号[];
/*链表节点*/
类型定义结构节点{
字符*数据;
结构节点*下一步;
}节点;
node*start=NULL;
节点*电流;
/*将节点追加到链表*/
无效添加(字符*行){
node*temp=malloc(sizeof(node));
温度->数据=strdup(行);
temp->next=NULL;
电流=启动;
if(start==NULL){
启动=温度;
}否则{
while(当前->下一步!=NULL){
当前=当前->下一步;
}
当前->下一步=温度;
}
}
/*读取文本文件*/
无效读取文件(字符*文件名){
FILE*FILE=fopen(文件名,“r”);
if(file==NULL){
出口(1);
}
字符缓冲区[512];
while(fgets(buffer,sizeof(buffer),file)!=NULL){
添加(缓冲区);
}
fclose(文件);
}
/*设置初始破折号字符串*/
void setInitDash(){
int i;
对于(i=0;inext;
}
秘密=p->数据;
setInitDash();
}
/*检查猜测是否正确*/
void checkGuess(){
int i,j=strlen(秘密)-1;
对于(i=0;i!=j;i++){
if(秘密[i]==猜测){
破折号[我]=猜测;
分数++;
}
}
}
/*检查分数是否有变化*/
无效检查分数(){
如果(分数=0){
misses++;
机会--;
incorrGuess[未命中]=猜测;
}
否则{
得分=0;
}
printf(“%s”,破折号);
}
/*打印当前电路板*/
作废印制板(){
printf(“uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
printf(“\n\n当前单词:”);
checkGuess();
检查分数();
printf(“机会:%d次错误猜测:”,机会);
对于(int i=0;i您从未初始化过“破折号”。给它一个大小,您应该会很好。我插入了50,破折号的替换工作正常。
**编辑**
仔细想想,我建议改用malloc/calloc/realloc。因此,将破折号声明为:
char*破折号;
然后,当您需要使用它时,分配空间:
void setInitDash(){
int i;
//calloc用0x00填充空格,确保字符串具有空终止符
破折号=calloc(strlen(secret)+1,sizeof(char);
//我不知道为什么你有strlen(秘密-1),strlen忽略了空终止符
对于(i=0;i
此代码的另一个大问题是:
if(破折号==secret)
将始终计算为FALSE,因为它比较地址破折号和秘密点,而不是值。要比较字符串,您需要比较每个数组成员,或者使用string.h中的strcmp函数。感谢帮助,我尝试使用'if(strcmp(破折号,秘密)==0){stillPlaying=2;}`但它不起作用。字符串的末尾有新行字符。最简单的解决方案是使用长度受限的字符串与``strncmp(破折号,secret,strlen(secret)-1)进行比较``。测试揭示了另一个问题:在玩家在最后一个正确字母后输入另一个字符之前,评估不会发生。这是一个流程问题,可以通过使用do…while循环而不是while…循环来解决。另外,保留新行对于这个应用程序来说也很好,但对于更大的问题,我会重构readfile函数以确保忽略它们。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int nodeNum, chances, misses, score, corrGuess;
char* secret;
char incorrGuess[50], guess, dashes[];
/*Node of linked list*/
typedef struct node {
char *data;
struct node *next;
} node;
node *start = NULL;
node *current;
/*Appending nodes to linked list*/
void add(char *line) {
node *temp = malloc(sizeof(node));
temp->data = strdup(line);
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}
/*read text file*/
void readfile(char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL) {
exit(1);
}
char buffer[512];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
add(buffer);
}
fclose(file);
}
/*Set initial dashes string*/
void setInitDash(){
int i;
for(i=0; i < strlen(secret)-1; i++){
dashes[i] = '-';
}
}
/*Generate random number between 0 and 2999*/
void randNum(int lower, int upper)
{
srand(time(0));
nodeNum = (rand() % (upper - lower + 1)) + lower;
}
/*Choose random node based on random number generated*/
void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
for(n = 0; n != nodeNum; n++)
{
p = p->next;
}
secret = p->data;
setInitDash();
}
/*Check guess for correct guess*/
void checkGuess(){
int i, j = strlen(secret) - 1;
for(i = 0; i != j; i++){
if(secret[i] == guess) {
dashes[i] = guess;
score++;
}
}
}
/*Check if score changes*/
void checkScore(){
if(score == 0){
misses++;
chances--;
incorrGuess[misses] = guess;
}
else{
score = 0;
}
printf("%s", dashes);
}
/*Print current board*/
void printBoard(){
printf("__________________________________________________________________\n");
printf("\n\nCurrent Word: ");
checkGuess();
checkScore();
printf(" Chances: %d Incorrect Guesses: ", chances);
for(int i = 0; i <= misses; i++)
printf("%c", incorrGuess[i]);
printf("\nPlease enter your guess: ");
scanf(" %c", &guess);
printf("\n__________________________________________________________________\n");
}
/*Function for if player wins*/
void winCase(){
printf("\n\n\n\n\nGood Job! You have guessed the word correctly. Restart the program to play again!");
}
/*Function for if player loses*/
void loseCase(){
printf("\n\n\n\n\nUnfortunately, you have run out of chances. The word to guess was %s.", secret);
}
int main(){
int i;
score = 0;
corrGuess = score;
int stillPlaying = 1;
printf("Hello User, Welcome to Hangman\nPlease enter number of chances you would like: "); /*Welcome Message*/
scanf("%d", &chances);
readfile("words.txt"); /*Readfile and choose random word*/
randNum(0, 2999);
chooseRand(start);
printf("%s", secret); /*Print secret word for easy testing*/
printf("__________________________________________________________________\n"); /*Print first iteration of the board*/
printf("\n\nCurrent Word: %s", dashes);
printf(" Chances: %d Incorrect Guesses: %s", chances, incorrGuess);
printf("\nPlease enter your guess: ");
scanf(" %c", &guess);
printf("\n__________________________________________________________________\n");
while(stillPlaying == 1){ /*While loop to print board until win or lose case is true*/
printBoard();
if(dashes == secret){
stillPlaying = 2;
}
else if(chances <= 0){
stillPlaying = 0;
}
}
if(stillPlaying == 0){
loseCase();
}
else if(stillPlaying == 2){
winCase();
}
return 0;
}