Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 有没有办法在C中存储一个数组,其中的值在不同的索引处循环?_Arrays_C_Linked List - Fatal编程技术网

Arrays 有没有办法在C中存储一个数组,其中的值在不同的索引处循环?

Arrays 有没有办法在C中存储一个数组,其中的值在不同的索引处循环?,arrays,c,linked-list,Arrays,C,Linked List,我正在用C语言创建一个Hangman项目,其中要猜测的单词由破折号表示,随着游戏的进行,破折号将被正确的猜测所取代。我用一个链表来存储所有的单词。我已经弄清楚了几乎所有的功能,但是,我的最新版本的游戏运行得非常完美,除非单词中有一个重复出现的角色需要猜测。之所以会出现这种情况,是因为我创建了一个函数,该函数可以从用户那里进行猜测,并将其与秘密字进行比较。如果对“secret”字符串的特定索引的猜测是正确的,它会将破折号字符数组的索引设置为相同的猜测(并显示破折号供玩家猜测)。问题在于破折号字符串

我正在用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;
}