关于多项选择题程序的问题

问题描述

我创建了一个程序来生成多项选择考试的结果。该程序应该显示错误总数,空白答案和错误回答的问题数量。对于以下输入: 6

1..223 (此处.表示空白)

123124

输出应该是:

Your result:

Mistakes: 3

Blanks: 2

Your mistakes are following:

4 5 6

Your blanks are following:

2 3

但是代码显示了未定义的行为。它似乎经历了无限循环。期待很快解决我的问题。预先感谢。

#include <stdio.h>
#include <stdlib.h>



typedef struct node
{
    char data;
    struct node* next;
}node;

void printNode(node* head)
{
    node* local = head;
    int i = 0;
    if(local -> data == 0)
    {
        printf("0");
        return;
    }

    while(local != NULL)
    {
        if(i == 3)
        {
            i = 0;
            printf("\n");
        }


        printf("%d\t",local -> data);
        local = local -> next;
        ++i;

    }
}

void freeNode(node** head)
{
    node* temp = (*head);

    while((*head) != NULL)
    {
        (*head) = (*head) -> next;
        free(temp);
        temp = (*head);
    }
}
int main()
{
    int n,i,flagB,flagM,blnk,mstk;
    blnk = mstk = flagB = flagM = 0;

    printf("Enter the number of questions: ");
    scanf("%d",&n);

    char ques[n],ans[n];

    if(n == 0)
        return 0;

    node* headM = (node*)malloc(sizeof(node));

    node* nodeM;

    node* headB = (node*)malloc(sizeof(node));

    node* nodeB;

    printf("Enter your given answers: ");
    fflush(stdin);
    for(i = 0; i < n; ++i)
    {
        scanf("%c",&ques[i]);
    }

    fflush(stdin);
    ques[n] = '\0';

    printf("Enter the solution: ");

    for(i = 0; i < n; ++i)
    {
        scanf("%c",&ans[i]);
    }

    ans[n] = '\0';

    for(i = 0; i < n; ++i)
    {
        if(ques[i] == '.')
        {
            ++blnk;
            if(flagB == 0)
            {
                headB -> data = i + 1;
                headB -> next = NULL;
                nodeB = headB;
                continue;
            }

            nodeB -> next = (node*)malloc(sizeof(node));
            nodeB = nodeB -> next;
            nodeB -> data = i + 1;
            nodeB-> next = NULL;
            flagB = 1;
        }
        else if(ques[i] != ans[i])
        {
            ++mstk;

            if(flagM == 0)
            {
                headM -> data = i + 1;
                headM -> next = NULL;
                nodeM = headM;

                continue;
            }

            nodeM -> next = (node*)malloc(sizeof(node));
            nodeM = nodeM -> next;
            nodeM -> data = i;
            nodeM-> next = NULL;
            flagM = 1;

        }

    }



    printf("Your result:\n\tMistakes: %d\n\tBlanks: %d\n",mstk,blnk);

    printf("Your mistakes are follwing:\n");
    printNode(headM);

    printf("\nYour blanks are follwing:\n");
    printNode(headB);

    freeNode(&headM);
    freeNode(&headM);

    return 0;
}

解决方法

我对此代码做了一些更改,请检查一下。

#include <stdio.h>
#include <stdlib.h>

typedef struct Node node;
struct Node
{
  int data;
  struct Node * next;
};

void printNode(node *head)
{
node *local = head;
while (local != NULL)
{
    printf("%d ",local->data);
    local = local->next;
}
}

void freeNode(node **head)
{
node *temp = (*head);

while ((*head) != NULL)
{
    (*head) = (*head)->next;
    free(temp);
    temp = (*head);
  }
  }
 int main()
 {
int n,i,flagB = 0,flagM = 0,blnk = 0,mstk = 0;
blnk = mstk = flagB = flagM = 0;

printf("Enter the number of questions: ");
scanf("%d",&n);

char ques[n],ans[n];

if (n == 0)
    return 0;

node *headM = (node*) malloc(sizeof(node));
headM->data = 0;
node *nodeM = headM;

node *headB = (node*) malloc(sizeof(node));
headB->next = 0;
node *nodeB = headB;

printf("Enter your given answers: ");

for (i = 0; i < n; ++i)
{
    scanf("%s",&ques[i]);
}

ques[n] = '\0';
fflush(stdin);

printf("Enter the solution: ");

for (i = 0; i < n; ++i)
{
    scanf("%s",&ans[i]);
}

ans[n] = '\0';
fflush(stdin);

for (i = 0; i < n; ++i)
{
    if (ques[i] == '.')
    { ++blnk;
        if (flagB == 0)
        {
            nodeB->data = i + 1;
            nodeB->next = NULL;
            flagB = 1;
            continue;
        }

        nodeB->next = (node*) malloc(sizeof(node));
        nodeB = nodeB->next;
        nodeB->data = i + 1;
        nodeB->next = NULL;
    }
    else if (ques[i] != ans[i])
    { ++mstk;
        if (flagM == 0)
        {
            nodeM->data = i + 1;
            nodeM->next = NULL;
            flagM = 1;
            continue;
        }

        nodeM->next = (node*) malloc(sizeof(node));
        nodeM = nodeM->next;
        nodeM->data = i + 1;
        nodeM->next = NULL;
        //flagM = 1;    //You made a mistake here
    }
}

nodeM = headM;
nodeB = headB;

printf("Your result:\n\tMistakes: %d\n\tBlanks: %d\n",mstk,blnk);

printf("Your mistakes are following question numbers:\n");
if (mstk != 0)
    printNode(headM);
else
    printf("No Mistakes\n");

printf("\nYour blanks are following question numbers:\n");
if (blnk != 0)
    printNode(headB);
else
    printf("No Blanks\n");

freeNode(&headM);
freeNode(&headM);

return 0;
}
,

这里还有一些其他想法。是什么让您的代码非常复杂,难以调试且难以保持逻辑正确,是因为您在空白和错误的逻辑内混合了链表 Add 函数,并使用特殊条件来处理添加第一个节点和后续节点。这使测试和调试变得困难。如果需要将节点添加到链接列表,请编写一个add()函数,在将其用于代码之前,可以对其进行彻底的测试和调试。

您的VLA quesans太短,无法容纳一串n字符,至少它们必须长n + 1个字符才能为 nul-termining 字符,用于标记字符串的结尾。理想情况下,您将使它们至少长2个字符,以同时容纳'\n',这将允许您使用fgets()进行输入,而不是一次循环scanf()一个字符-只是疯了。

您无需将指针的地址传递给freeNode(),只需传递一个指针即可。当然freeNode()将收到该指针的副本-但它将包含原始地址-并且由于您无需对该指针进行任何更改即可返回给调用者,因此无需传递指针的地址(完成后不会再担心任何其他列表了……)

因此,将这些部分放在一起,添加一个add()函数以添加到您的链接列表中(请参阅Linus on Understanding Pointers,以了解为什么使用指针对指针进行迭代)。简单的empty_stdin()函数可从'\n'读取stdin来清除n剩余的scanf(),然后再向{{1} }和fgets(),您可以这样做:

ques

那里有很多东西,所以慢慢来。

使用/输出示例

ans

注意:#include <stdio.h> #include <stdlib.h> #include <string.h> /* simple function to empty stdin to end-of-line */ void empty_stdin (void) { int c = getchar(); while (c != '\n' && c != EOF) c = getchar(); } typedef struct node { int data; struct node *next; } node; node *add(node **head,int v) { node **ppn = head,/* pointer to pointer to head */ *pn = *head,/* pointer to head */ *newn = malloc (sizeof *newn); /* allocate new node */ if (!newn) { /* validate allocation */ perror ("malloc-node"); return NULL; } newn->data = v; /* initialize members values */ newn->next = NULL; while (pn) { /* iterate to end of list */ ppn = &pn->next; pn = pn->next; } return *ppn = newn; /* add & return new node */ } void printNode (node *head) { for (; head; head = head->next) printf (" %d",head->data); putchar ('\n'); } void freeNode(node *head) { while (head != NULL) { node *victim = head; head = head->next; free(victim); } } int main() { int n,blnk,mstk; blnk = mstk = 0; node *headM = NULL; /* declare pointers and initialize NULL */ node *headB = NULL; printf ("Enter the number of questions: "); /* you must VALIDATE every user-input */ if (scanf ("%d",&n) != 1) { fputs ("error: invalid integer input.\n",stderr); return 1; } empty_stdin(); /* remove '\n' (and any other chars from user) */ /* before calling fgets() below */ if (n == 0) /* check 0 BEFORE VLA declaration */ return 0; char ques[2*n],ans[2*n]; /* declare question/answer VLAs,don't skimp */ printf("Enter your given answers: "); if (!fgets(ques,sizeof ques,stdin)) /* read ques from stdin */ return 1; ques[strcspn(ques,"\r\n")] = 0; /* trim '\n' from end of ques */ printf("Enter the solution: "); if (!fgets(ans,sizeof ans,stdin)) /* read ans from stdin */ return 1; ans[strcspn(ans,"\r\n")] = 0; /* ditto for ans */ for(i = 0; i < n; ++i) /* loop n times */ { if(ques[i] == '.') /* if blank */ { add (&headB,i + 1); /* add to list headB */ ++blnk; /* increment counter */ } else if(ques[i] != ans[i]) /* if mistake */ { add (&headM,i + 1); /* add to list headM */ ++mstk; /* increment counter */ } } printf ("Your result:\n\tMistakes: %d\n\tBlanks: %d\n" "Your mistakes are following:\n",blnk); printNode(headM); printf("\nYour blanks are following:\n"); printNode(headB); freeNode(headM); /* no need to pass the address of the pointer to free */ freeNode(headB); /* there won't be a list left when freeNode is done */ return 0; } $ ./bin/llquestions Enter the number of questions: 6 Enter your given answers: 1..223 Enter the solution: 123124 Your result: Mistakes: 2 Blanks: 2 Your mistakes are following: 4 6 Your blanks are following: 2 3 中,1..223并非错误,123124在末尾的正确位置)

仔细检查一下,如果还有其他问题,请告诉我。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...