这个函数应该从一个名为"newtext.txt"
的文件(在我的代码中由path定义(中读取单行输入,提取该行中的第一个单词并将其用作链表每个元素的名称字段(然后打印(。
这是我写的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct user {
char name[50];
struct user* next;
};
int main() {
unsigned i = 0;
struct user *temp = NULL
struct user *aux = NULL;
FILE* file_pointer = fopen("/home/marco/Desktop/suite1/newtext.txt", "r");
if(file_pointer == NULL) {
printf("nWarning! File not opened properly!n");
return -1;
}
char vector[100];
char sub_v[50];
while(fgets(vector, sizeof(vector), file_pointer) != NULL) {
while(vector[i] != ' ' && i < (sizeof(sub_v) - 1)) {
sub_v[i] = vector[i];
i++;
}
sub_v[i] = ' ';
i++;
if(temp == NULL) { //first element in the list;
temp = malloc(sizeof(struct user));
aux = temp;
strcpy(temp -> name, sub_v);
temp -> next = NULL;
} else {
temp -> next = malloc(sizeof(struct user));
temp = temp -> next;
temp -> next = NULL;
strcpy(temp -> name, sub_v);
}
}
while(aux != NULL) {
puts(aux -> name);
aux = aux -> next;
}
fclose(file_pointer);
return 0;
}
包含的文件是:
andrew michael jonathan
frank
marcus raquis
freddie
预期输出应为:
andrew
frank
marcus
freddie
但它是:
andrew
andrew
andrew
andrew
似乎使用相同的输入线重复while循环,但我不知道如何解决此问题。
变量 i 不会在 while 循环中重新初始化
while(fgets(vector, sizeof(vector), file_pointer) != NULL) {
因此内循环
while(vector[i] != ' ' && i < (sizeof(sub_v) - 1)) {
sub_v[i] = vector[i];
i++;
}
具有未定义的行为。
在外部循环中声明变量 i。例如
while(fgets(vector, sizeof(vector), file_pointer) != NULL) {
unsigned i = 0;
while(vector[i] != ' ' && i < (sizeof(sub_v) - 1)) {
sub_v[i] = vector[i];
i++;
}
而这句话
i++;
是多余的,没有意义。
以及此循环中的条件
while(vector[i] != ' ' && i < (sizeof(sub_v) - 1)) {
最好替代
#include <ctype.h>
// ...
while( !isspace( ( unsigned char )vector[i] ) && i < (sizeof(sub_v) - 1)) {
好的,所以这里发生的事情是你忘了在while循环的开头将变量'i'设置为0。
循环第一次运行时,它工作得很好,第一行被写入arrray向量,第一个单词被复制到sub_v和节点的name变量中。
数组sub_v现在如下所示:
['a', 'n', 'd', 'r', 'e', 'w', ' ', (garbage values), ...]
但是 - 在下一次迭代中,由于 'i' 没有设置回 0,垃圾值从向量复制到sub_v的末尾(在 '\0' 之后(。
输出是单词"andrew"4次的原因是因为当执行此行时:
strcpy(temp->name, sub_v);
它只复制字符,直到终止空字节 '\0',因为这就是 strcpy(3( 的工作方式(复制一个字符串(。"\0"表示字符串的结尾,它之后的所有内容都不被视为字符串的一部分。
所以数组sub_v的开头每次都打印("andrew"(,这让你认为问题出在 fgets 循环同一行,但问题的根源不是在每次循环迭代时将 'i' 变量设置为 0。
顺便说一句,你检查了 fopen 的返回值并在最后关闭了文件,这很好,你应该对malloc(3(做同样的事情,不要忘记释放你为每个节点分配的内存。