【问题标题】:C: Simple CSV reader/writer - infinite loop behaviorC:简单的 CSV 读取器/写入器 - 无限循环行为
【发布时间】:2019-01-03 17:43:50
【问题描述】:

我的程序会编译,但是当我运行 exe 时,没有输出,程序也没有终止。

我试图通过打印“flags;”来查找可能导致问题的代码行但是,我的标志都没有被打印出来,即使是 main 中第一个语句的标志。如果不调用函数populateLinkedList,程序将正常执行。

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

//Declare Node
struct TransactionNode{
    char id[11];
    char accountDebit[11];
    char accountCredit[11];
    char debit[11];
    char credit[11];
    char date[11];
    char message[101];

    struct TransactionNode *nextPtr; // pointer to next node
};

//Rename Node and Node Pointer
typedef struct TransactionNode Node; //ListNode is synonym for struct listNode
typedef Node *NodePtr; //ListNodePtr is a pointer to ListNode

//Declare starting transaction node
NodePtr tSPtr = NULL;

//prototypes
void writeLinkedList(NodePtr sPtr);
void populateLinkedList(void);

int main(){
    printf("hello");
    writeLinkedList(tSPtr);
    populateLinkedList(); 
    writeLinkedList(tSPtr);
    return 0;
}

void writeLinkedList(NodePtr sPtr){
    FILE *fPtr;
    NodePtr currentPtr;
    currentPtr = sPtr; //assign currentPtr to startingPtr
    fPtr = fopen("records.dat", "w");

    while(currentPtr != NULL){//while currentPtr exists
        //write structure
        fprintf(fPtr, "%s;%s;%s;%s;%s;%s;%s;", currentPtr -> id, currentPtr -> accountDebit, 
        currentPtr -> accountCredit, currentPtr -> debit, currentPtr -> credit, currentPtr -> date, currentPtr ->message);
        //walk... 
        currentPtr = currentPtr -> nextPtr;
    }//end while

    fclose(fPtr);
}

void populateLinkedList(void){
    FILE *fPtr;
    NodePtr currentPtr;
    NodePtr previousPtr;
    char temp[101];
    //check to see if file can be opened
    if (( fPtr = fopen("records.dat", "r")) == NULL){
        printf("populateLinkedList error: Cannot open file"); //error
        return;
    } //end if

    //create first node
    currentPtr = malloc(sizeof(Node));
    if(currentPtr == NULL){
        fclose(fPtr);
        printf("populateLinkedList error: Not enough memory");
        return;
    }//end if
    else tSPtr = currentPtr; //end else: assign first node to sPtr

    //FOR FIRST TRANSACTION:
    //flush and scan and assign id
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    printf("%s", temp);
    if(temp[0] == EOF){
        fflush(stdin);
        fclose(fPtr);
        return;
    }; //end if: if EOF is found break function
    strcpy(currentPtr -> id, temp);
    //flush and scan and assign debit account id
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    strcpy(currentPtr -> accountDebit, temp);
    //flush and scan and assign credit account id
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    strcpy(currentPtr -> accountCredit, temp);
    //flush and scan and assign debit amount
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    strcpy(currentPtr -> debit, temp);
    //flush and scan and assign credit amount
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    strcpy(currentPtr -> credit, temp);
    //flush and scan and assign date
    fflush(stdin);
    fscanf(fPtr, "%10[^;]", temp);
    strcpy(currentPtr -> date, temp);
    //flush and scan and assign message
    fflush(stdin);
    fscanf(fPtr, "%100[^;]", temp);
    strcpy(currentPtr -> credit, temp);
    //assign nextPtr
    currentPtr -> nextPtr = NULL;

    //assign currentPtr to previousPtr
    previousPtr = currentPtr;

    while(temp[0]!= EOF){

        //create first node
        currentPtr = malloc(sizeof(Node));
        if(currentPtr == NULL) break;

        //flush and scan and assign id
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        if(temp[0] == EOF) break; //end if: if EOF is found break function
        strcpy(currentPtr -> id, temp);
        //flush and scan and assign debit account id
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        strcpy(currentPtr -> accountDebit, temp);
        //flush and scan and assign credit account id
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        strcpy(currentPtr -> accountCredit, temp);
        //flush and scan and assign debit amount
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        strcpy(currentPtr -> debit, temp);
        //flush and scan and assign credit amount
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        strcpy(currentPtr -> credit, temp);
        //flush and scan and assign date
        fflush(stdin);
        fscanf(fPtr, "%10[^;]", temp);
        strcpy(currentPtr -> date, temp);
        //flush and scan and assign message
        fflush(stdin);
        fscanf(fPtr, "%100[^;]", temp);
        strcpy(currentPtr -> credit, temp);
        //assign nextPtr
        currentPtr -> nextPtr = NULL;

        //assign currentPtr to previousPtr
        previousPtr = currentPtr;

        //assign currentPtr to previousPtr -> nextPtr
        previousPtr -> nextPtr = currentPtr;
    }//end while

    fflush(stdin);
    fclose(fPtr);
    return;
}



I expect the file to remain the same, the flags be printed, and the program to terminate; however, the flags are not printed and the program does not terminate.

【问题讨论】:

  • temp[0] == EOF 永远不会是真的,因为fscanf 不会那样工作
  • fflush(stdin) 产生未定义的行为
  • 而且你绝对不想要fflush(stdin);,因为除了与这样做相关的其他问题之外,你甚至没有阅读stdin 的内容
  • 所以我可以取出 fflush(stdin) 吗?另外,我如何从 fscanf 读取 EOF?

标签: c csv stdio string.h


【解决方案1】:

populateLinkedList 你在内存中创建了一个圆圈:

previousPtr = currentPtr;

//assign currentPtr to previousPtr -> nextPtr
previousPtr -> nextPtr = currentPtr;

在那之后currentPtr-&gt; nextPtr == currentPtr,如果你试图遍历你的列表,你的程序会无限循环,一个循环没有尽头

必须交换线路:

//assign currentPtr to previousPtr -> nextPtr
previousPtr -> nextPtr = currentPtr;

previousPtr = currentPtr;

【讨论】:

  • 所以我需要做的是:previousPtr -> nextPtr = currentPtr; previousPtr = currentPtr;
猜你喜欢
  • 2013-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 1970-01-01
  • 2023-01-04
  • 1970-01-01
  • 2014-10-10
相关资源
最近更新 更多