问题陈述:给出参与某项特定调查的国家/地区和女性和男性人数列表。程序是按照有关男性和女性总数的降序对列表进行排序,从SecondaryEd2005.txt文件中读取列表。问题必须仅使用链表解决,而不是双链表。不允许使用数组进行预分类。成员必须是:char指向国家名称,2对女性和男性参与者的长度。必须动态分配国家/地区名称的空间。输出必须采用国家名称,女性参与者数量,男性参与者数量,总和,终点等格式。
问题:在任何情况下,代码都会输出最后读取的国家/地区名称,而它会提供有关男性和女性数量及其总和的正确输出,它们按降序排列。我尝试输出新节点的成员,然后将它放在列表的正确位置,并提供正确的输出,表明所有内容都已正确读取。 我认为有一些国家名称是动态分配的,但不确定它,如果它是正确的,不知道到底是什么。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _person_count {
char* country;
long females;
long males;
struct _person_count *link;
} person_count;
int main () {
FILE *file;
file = fopen("SecondaryEd2005.txt","r");
person_count *first = NULL;
char c[32];
int male;
int female;
do {
person_count *newNode = malloc(sizeof(person_count));
fscanf(file, "%s %i %i %i", c, &female, &male);
newNode->females = female;
newNode->males = male;
int n;
n = strlen(c);
newNode->country = malloc(n*sizeof(char));
newNode->country = c;
newNode->link = NULL;
printf("still reading: %s %i %i \n", newNode->country, newNode->females, newNode->males);
if(first == NULL) {
first = newNode;
} else {
int sumnewNode = newNode->females + newNode->males;
int sumFirst = first->females + first->males;
if(sumnewNode > sumFirst) {
newNode->link = first;
first = newNode;
}else {
person_count* current = first;
while (1)
{
if (current->link == NULL)
{
current->link = newNode;
break;
}
else if (current->link->females + current->link->males < sumnewNode)
{
newNode->link = current->link;
current->link = newNode;
break;
}
current = current->link;
}
}
}
} while(!feof(file));
person_count* cur = first;
while(1)
{
printf("%s %d %d %d\n", cur->country, cur->females, cur->males, cur->females + cur->males);
if (cur->link == NULL)
break;
cur = cur->link;
}
return 0;
}
如果需要任何其他信息,我可以提供。提前谢谢。
答案 0 :(得分:1)
strlen()返回字符串的长度,不带 null终结符。这很重要(基本上你想要newNode->country = malloc(n+1);
,sizeof(char)
总是1)。
更糟糕的是,在你重写newNode->country
之后,丢失指向已分配块的指针并将newNode->country
设置为指向32-char缓冲区(所以在所有节点中最后country
指针指向相同的字符串)。应使用strncpy() or strncpy_s()调用进行字符串复制。
答案 1 :(得分:1)
你有几个错误:
<form action="#" class="input-group" data-bind="css: { focused: isPathFocused() }, submit: function(){$root.reload(true);}">
<label for="path">Path:</label>
<span class="prefix" data-bind="text: domain">https://www.google.com</span>
<input type="text" id="path" name="path" data-bind="hasfocus: isPathFocused, value: path">
<button type="submit" id="load-page-button">Load</button>
</form>
<button id="preview-toggle" class="preview-toggle-button" data-bind="attr: { title: viewState.isCollapsed() ? 'Expand preview pane' : 'Collapse preview pane' },
click: $root.viewState.collapseOnClick,
css: { collapsed: viewState.isCollapsed },
text: viewState.isCollapsed() ? 'Expand' : 'Collapse'" title="Collapse preview pane">Collapse</button>
<button id="preview-toggle-close" class="preview-toggle-button" data-bind="click: $root.viewState.closeOnClick" title="Close preview pane">Close</button>
C字符串应该是NUL终止的,而<head>
<script async="" src="//www.google-analytics.com/analytics.js"></script>
<script type="text/javascript" async="" src="//cdn3.optimizely.com/js/geo2.js"></script>
<script type="text/javascript" async="" src="https://vis.optimizely.com/api/targetingEmbed/5935064/3375340400/oeu1445896359844r0.5723679552320391"></script>
<script type="text/javascript" async="" src="//cdn3.optimizely.com/js/geo2.js"></script>
<script type="text/javascript" async="" src="https://optimizely.skymosity.com/sp.js?callback=optimizely_skymosity"></script>
<meta charset="utf-8">
<title>Optimizely Preview</title>
<link rel="stylesheet" type="text/css" href="/master-2185.388478123618610666/dist/css/preview.css">
<script src="/master-2185.388478123618610666/dist/js/preview2.js"></script><style type="text/css"></style>
<script type="text/javascript" src="//cdn.optimizely.com/js/5935064.js"></script>
<script src="https://odds.optimizely.com/js/geo2.js?c__mkto_trk=id%3A361-GER-922%26token%3A_mch-optimizely.com-1445896362127-52041&project=5935064" type="text/javascript"></script>
<script src="https://vis.optimizely.com/api/targetingEmbed/5935064/3375340400/oeu1445896359844r0.5723679552320391" type="text/javascript"></script>
<iframe src="https://5935064.cdn.optimizely.com/client_storage/5935064.html"></iframe>
</head>
并不能解释这一点。也许在这里使用 n = strlen(c);
newNode->country = malloc(n*sizeof(char));
newNode->country = c;
会更好:
strlen()
当您拆除列表时,您仍然需要strdup()
内存。
此外,您的版本会泄漏内存,因为您实际上从未使用过您分配的缓冲区。这一行:
newNode->county = strdup(c);
将country设置为指向堆栈上的缓冲区,该缓冲区将消失,指针指向无效内存 - 或者更糟糕的是,有效内存不是您自己的内存。至少,对于扫描的每一行,它都会被破坏,这使得所有节点都指向最后读取的国家/地区。如果您要坚持分配自己的记忆,那应该更像是:
free()