为什么继续导致未定义的行为

问题描述

我用 C 创建了一个程序,它从文件中读取单词并将它们存储到一个链表中,但我注意到第二个 continue 导致未定义的行为 为什么会这样?

有3个功能

一个函数创建了一个很好的列表

第二个函数用数据填充列表

第三个显示列表的内容

当我运行时,程序被调用为未定义的行为

文件https://gist.github.com/up1047388/b3018bc2a1fb0d66e86855a0d54baf63

我的代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    typedef struct node {
        char str[50];
        struct node *next;
    }Node;
    
    void createList(Node ** head,int len )
    {   int i=0;
        Node **lpp ;
        Node *komvos ;
        Node *komvos1;
        komvos = (Node*)malloc(sizeof(Node));
        komvos -> next = NULL;
        lpp=&komvos;
        for(i=1 ; i < len ; i++)
        {
            komvos1 = (Node*)malloc(sizeof(Node));
            komvos1 -> next = NULL;
            (*lpp) -> next = komvos1;
            lpp = &(*lpp) -> next;
        }
        
        *head = komvos ;
    }
    
    void FileList(FILE *fp,Node *head) 
    {   char c;
        char tempStr[50];
        char str[50];
        int i = 0,j = 0;
        Node **lpp;
        lpp=&head;
        
    for(c=fgetc(fp) ; c!=EOF ; c=fgetc(fp))
    {
        str[j]=c;
        j++;
        }   
    str[j]='\0';    
    j=0;    
    
    while(str[j]!='\0')  
    {   
        
        if (str[j] == ' ')
        {
            if (i == 0)
            {
                continue;
            }
            
            tempStr[i] = '\0';
            i = 0;
            
            
             strcpy((*lpp) -> str,tempStr);
             
             lpp = &(*lpp)  -> next ;       
            
            //continue  //This continue caused the problem
        }
        
        tempStr[i] = str[j];
        i++;
        j++;
        
        
    }   
        
    }
    
    void printList(Node *head)
    {
        Node *temp;
        temp = head;
        for(;temp!=NULL;temp=temp->next)
        {
            printf("\nthe words are  : %s",temp -> str);
        }
        
    }
    
    
    int main ()
    {   
    
        Node *head ;
        head = NULL;
        FILE *fp;
        fp = fopen ("lists4.txt","r+");
        if (fp==NULL)
        {
            printf("the file is broken");
            exit(8);
        }
        
        createList(&head,3);
        FileList(fp,head);
        printList(head);
        
        return 0;
}

解决方法

注释掉的 continue 将使循环无限运行,因为它会阻止 j 被更新。

为避免这种情况,在 j 情况下,在 continue 之前添加代码以更新 str[j] == ' '

    while(str[j]!='\0')
    {
        
        if (str[j] == ' ')
        {
            j++; /* add this to update j */
            if (i == 0)
            {
                continue;
            }
            
            tempStr[i] = '\0';
            i = 0;
            
            strcpy((*lpp) -> str,tempStr);
            
            lpp = &(*lpp)  -> next ;
            
            continue;  /* and then turn on the continue */
        }
        
        tempStr[i] = str[j];
        i++;
        j++;
        
    }

在这种情况下,我更喜欢使用 if-else

    while(str[j]!='\0')
    {
        
        if (str[j] == ' ')
        {
            j++;
            if (i == 0)
            {
                continue;
            }
            
            tempStr[i] = '\0';
            i = 0;
            
            strcpy((*lpp) -> str,tempStr);
            
            lpp = &(*lpp)  -> next ;
        }
        else
        {
            tempStr[i] = str[j];
            i++;
            j++;
        }
        
    }