链表存储矩阵提取重复元素写入文件代码无输出问题排查
C语言链表矩阵提取全局重复元素问题排查
我用C语言实现了从CSV文件读取数据构建struct Node类型的链表矩阵,目的是提取全局重复元素并写入output_duplicate2.txt文件。
输入示例CSV内容:
4,8,45,0 3,56,4,9 12,3,5,90
预期输出文件内容:
4,3
但运行以下代码后输出文件为空,请问代码存在什么问题?
#include <stdio.h> #include <stdlib.h> // Define a structure for a node in the linked list struct Node { int data; struct Node* right; struct Node* down; }; // Function to add a new node to the matrix struct Node* addNode(struct Node* head, int data) { // Create a new node struct Node* nextNode = (struct Node*) malloc(sizeof(struct Node)); nextNode->data = data; nextNode->right = NULL; nextNode->down = NULL; // If the matrix is empty, make the new node the head if (head == NULL) { head = nextNode; } else { // Add the new node to the right of the last node in the row struct Node* temp = head; while (temp->right!= NULL) { temp = temp->right; } temp->right = nextNode; } return head; } void duplicate2(struct Node* head) { // Open the output file FILE* file = fopen("output_duplicate2.txt", "w"); // Traverse the matrix and print each row struct Node* row = head; struct Node* temp; while (row!= NULL) { struct Node* col = row; while (col!= NULL) { temp = col->right; if (temp!= NULL) { if (col->data == temp->data) { fprintf(file, "%d", col->data); } temp = temp->right; } temp = temp->down; if (temp == NULL) { col = col->right; } } row = row->down; } // Close the output file fclose(file); } int main() { // Open the input file FILE* file = fopen("input.csv", "r"); // Initialize variables int data; char ch; struct Node* head = NULL; struct Node* currentRow = NULL; struct Node* prevRow = NULL; // Read the input file character by character while ((ch = fgetc(file))!= EOF) { // If the character is a digit, add it to the current number if (ch >= 48 && ch <= 57) { data = data * 10 + (ch - 48); } // If the character is a comma, add the current number to the matrix else if (ch == ',') { currentRow = addNode(currentRow, data); data = 0; } // If the character is a newline, add the current row to the matrix and start a new row else if (ch == '\n') { currentRow = addNode(currentRow, data); data = 0; if (head == NULL) { head = currentRow; } else { prevRow->down = currentRow; } prevRow = currentRow; currentRow = NULL; } } // Close the input file fclose(file); duplicate2(head); return 0; }
代码存在的核心问题
1. 变量未初始化导致数据解析错误
main函数中int data;未初始化,第一次读取数字时data是随机垃圾值,会导致第一个数字的计算完全错误,链表中存储的初始数据不符合CSV内容。
2. CSV末尾数据未处理
如果CSV文件最后一行没有换行符,最后一个数字不会被添加到链表中,导致矩阵数据不完整,后续重复检测会遗漏元素。
3. 重复元素检测逻辑完全错误
duplicate2函数的遍历逻辑混乱:
- 仅检查同一行中相邻的下一个元素,完全没有实现全局重复的检测逻辑(全局重复需要统计所有元素的出现次数,找出出现≥2次的元素);
- 存在空指针访问风险:当
temp为NULL时(比如一行的最后一个节点),执行temp = temp->down会触发未定义行为,可能导致程序崩溃或逻辑混乱; - 循环条件错误,
if (temp == NULL) { col = col->right; }的逻辑无法正确遍历所有元素。
4. 链表行连接逻辑有漏洞
只有当遇到换行符时才会连接前一行和当前行,若最后一行没有换行,prevRow->down不会被设置,导致矩阵行之间的连接不完整。
修复方案
1. 初始化变量
在main中将data初始化为0:
int data = 0;
2. 处理文件末尾的最后一个数字
在while循环结束后,补充处理无换行的最后一行:
// 处理文件末尾没有换行的情况 if (currentRow != NULL && data != 0) { currentRow = addNode(currentRow, data); if (head == NULL) { head = currentRow; } else { prevRow->down = currentRow; } }
3. 重构重复元素检测逻辑
通过统计所有元素的出现次数来提取全局重复元素,示例重构后的duplicate2:
void duplicate2(struct Node* head) { FILE* file = fopen("output_duplicate2.txt", "w"); if (!file) return; // 假设元素范围是0-100,可根据实际情况调整 int count[101] = {0}; struct Node* row = head; // 遍历矩阵统计元素出现次数 while (row != NULL) { struct Node* col = row; while (col != NULL) { if (col->data >= 0 && col->data <= 100) { count[col->data]++; } col = col->right; } row = row->down; } // 写入重复元素,处理逗号格式 int first = 1; for (int i = 0; i <= 100; i++) { if (count[i] >= 2) { if (!first) { fprintf(file, ","); } fprintf(file, "%d", i); first = 0; } } fclose(file); }
4. 避免空指针访问
所有指针操作前必须检查是否为NULL,比如原duplicate2中的temp->down操作,需先判断temp != NULL。
内容的提问来源于stack exchange,提问作者user241575683695
相关产品推荐
相关产品推荐

