添加另一个循环后执行停止(C,Project Hangman)

Posted

技术标签:

【中文标题】添加另一个循环后执行停止(C,Project Hangman)【英文标题】:execution stops after adding another loop (C, Project Hangman) 【发布时间】:2017-04-10 13:25:17 【问题描述】:

你好 *** 社区, 我是编码新手,刚刚上过 2 周的 c 课程。 我们必须做一个项目,而我选择的项目是刽子手。 到目前为止一切正常,但是在添加了一个循环(for 或 while)以输出找到的字母之后,执行在输入字母后停止(所以在第 68 行之后)并且知道为什么。 我在 cygwin 上赢得 7 顺便说一句。 非常感谢您的帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
unsigned sleep( unsigned seconds );
void Welcome()

      printf("      WELCOME\n"); 
      //sleep(1);

void showLogo() 


      printf("            TO\n"); 
      //sleep(2);
      printf("--------------------------------------------  _______\n");
      printf("| H  H   A   N   N  GGGG M   M   A   N   N |  |/   | \n");
      printf("| H  H  A A  NN  N G     MM MM  A A  NN  N |  |/   | \n");
      printf("| HHHH AAAAA N N N G  GG M M M AAAAA N N N |  |    O \n");
      printf("| H  H A   A N  NN G   G M   M A   A N  NN |  |   \\|/\n");
      printf("| H  H A   A N   N  GGG  M   M A   A N   N |  |    | \n");
      printf("--------------------------------------------  |   / \\\n");
      printf("                                           __|_________\n\n");


void RandomWords()
   
//sleep(2);
FILE *h =  fopen("words.txt","r");
int zeichen = 0;
int anzahl_worte = 0;
if( fscanf(h, "%d\n", &anzahl_worte)!=1) //anzahl_worte(= number of words) been read out of words.txt

    printf("No valid word file. Missing number of words.");

char** var = calloc(anzahl_worte, sizeof(char*));
for(int i = 0; i < anzahl_worte; i++)

    var[i] = calloc(30, sizeof(char)); //every array has now 20 places free
    fscanf(h,"%49s", var[i]); //arrays are being filled with words


int zufall = rand() % anzahl_worte;
strcpy(var[0], var[zufall]);//arrays been chosen by random  
zeichen = strlen(var[0]);   
printf("Anzahl der gesuchten Buchstaben: %d\n", zeichen);
printf("Das gesuchte Wort ist übrigens : %s\n", var[0]);
fflush(stdout);
char strich[30];
char* p[30];

for(int i = 0; i < zeichen; i++) //"_" for every letter 
   
    strich[i] = '_';
    p[i] = &strich[i];
    printf("%c ", strich[i]);
                                //every "_" has a Pointer
                                //should later be replaced with a letter

//printf("\n%c\n", *p[0]);
char* letter[1];  //found letter will be saved here
int k = 0;  //position of the found letter in the word
//char** position = calloc(zeichen, sizeof(char**));
char* lpointer; //Addresse of the found letter 

printf("\nGeben Sie bitte Ihren Buchstaben ein\n");
scanf("%s", letter[0]); //Your chosen letter 
lpointer = strpbrk(var[0], letter[0]);  //letters been searched in the word 

if(lpointer != NULL)
       
    while (lpointer != NULL)
        
            k = lpointer - var[0];
            printf ("An der %d. Stelle gefunden\n",k+1);
            *p[k] = *lpointer; 
            lpointer = strpbrk(lpointer+1, letter[0]);
           


   

        for(int w = 0; w < zeichen; w++)
 
     printf("found letters: %c ", *p[w]);
 
/*printf("Gefundene Buchstaben %c ", *p[0]);
fflush(stdout);
printf("%c ", *p[1]);
fflush(stdout);
printf("%c ", *p[2]);
fflush(stdout);
printf("%c ", *p[3]);
fflush(stdout);
printf("%c ", *p[4]);
fflush(stdout);*/


fflush(h);
fclose(h);



   




int main (void)

    srand(time(NULL));

Welcome();

showLogo();

RandomWords();



【问题讨论】:

如果你添加了一些缩进,你的代码会更容易阅读。无论如何 - p 的目的是什么?为什么不用strich 而不是*p 第 3 周:缩进和代码格式化。 【参考方案1】:

您的scanf 会调用未定义的行为。

char* letter[1];

声明一个由一个char* 组成的单元初始化数组。然后您的scanf 尝试将用户输入放在letter[0] 指向的位置。它未初始化,因此您可以将用户输入放在内存中的任何位置。

实际上,它可能是一个小数字甚至 NULL 或指向尚未分配给您的进程的一些内存。无论哪种方式,可能的结果都是分段错误。

您需要为要放置输入的字符串分配一些存储空间。

char letter[2]; // Room for one letter and a '\0'

scanf("%1s", letter); // Only scan one letter

letter 可以在char* 用作字符串的任何地方使用,例如:

lpointer = strpbrk(lpointer+1, letter);

【讨论】:

【参考方案2】:

你可能想要这个:

  ...
  char letter[2];  //found letter will be saved here
  int k = 0;  //position of the found letter in the word
              //char** position = calloc(zeichen, sizeof(char**));
  char* lpointer; //Addresse of the found letter 

  printf("\nGeben Sie bitte Ihren Buchstaben ein\n");
  scanf("%c", letter[0]); //Your chosen letter 
  letter[1] = 0;  // NUL terminator
  lpointer = strpbrk(var[0], letter);  //letters been searched in the word 

  if (lpointer != NULL)
  
    while (lpointer != NULL)
    
      k = lpointer - var[0];
      printf("An der %d. Stelle gefunden\n", k + 1);
      *p[k] = *lpointer;
      lpointer = strchr(lpointer + 1, letter[0]);
    
  
  ...

但其他地方很可能存在更多问题。

顺便说一句:您应该只提交“全英文”课程,您可能会得到更多关注。但至少你的变量名和 cmets 是英文的。

在这里你应该检查fopen是否成功:

FILE *h =  fopen("words.txt","r");
if (h == NULL)

  printf("Can't open words file\n");
  exit(1);

【讨论】:

@4386427 因为他稍后将其用作单字母 NUL 终止的字符串。复制/粘贴更正,谢谢。 如果你使用%c,你不会自动从scanf得到一个空终止的字符串 @MichaelWalz Err,这就是我所说的。当我写评论时,这个 naswer 在 scanf 中有 %c @JeremyP 忘记我的评论,我误读了你的。刚刚更正了代码。 @4386427 而不是scanf("%1s", letter);【参考方案3】:

由于您只阅读一个字符,因此您可以这样做

char letter;
scanf("%c", &letter); //Your chosen letter
if(isalpha(letter))
  
  lpointer = strchr(var[0], letter);  //letters been searched in the word 

添加isalpha() 条件将确保也只检查字母表中的字母。

【讨论】:

【参考方案4】:

感谢这么多试图帮助我的人!

所以我尝试了你们所说的(除了 chris Turner 提议的)。但没有任何成功。 现在我发现如果我缩短数组 p 和 srich 的长度(strich 是单词每个字母的下划线),我可以使用更多的 printfs,并且不会出现分段错误等。 但是循环仍然不想工作 如果我添加多个 printfs 而不是循环该过程,但只要我使用循环来缩短该代码,则执行在字母输入(scanf 字母)之后停止。

【讨论】:

以上是关于添加另一个循环后执行停止(C,Project Hangman)的主要内容,如果未能解决你的问题,请参考以下文章

C程序在while循环后停止

为啥添加innerHTML后循环和数组停止工作?

labview停止循环为啥波形会清除一次

Arduino Mega 2560 - 成功执行多次后在 while 循环中停止代码执行

使用 system() 启动另一个可执行文件时程序停止

C#WinForm中如何实现长摁一个按钮button实现循环执行一个操作,放开就停止执行