我正在用C语言编写。我试图从文本文件中读取行,分析行,然后将一些信息放入字符串数组中。当我测试代码时,数组中的每个值似乎都是最后插入的值。是什么原因造成的?
int r;
char *users[51]; //given no more than 50 users
for (r = 0; r < 51; r++) {
int n = 15; //arbitrary guess at length of unknown usernames
users[r] = malloc((n + 1) * sizeof(char));
}
FILE *fp;
fp = fopen(argv[1], "r");
char *username;
int counter = 0;
char line[100];
while (fgets(line, 100, fp) != NULL) {
username = strtok(line, ":");
users[counter] = username;
printf("%s\n", username);
printf("%s\n", users[counter]);
//counter increase for later
counter += 1;
答案 0 :(得分:1)
您在数组中的每个条目中都添加了一个有意义的值:
users[r] = malloc((n+1) * sizeof(char));
但是您随后用一个无意义的值(指向line
的指针)覆盖了它:
users[counter] = username;
您大概想做的就是将username
指向的字符串复制到users[counter]
分配的空间中。 strcpy
函数可以做到这一点。
答案 1 :(得分:1)
strtok
是一个非常令人困惑的功能:
因此username
内的line
点。您将此指针存储到users[counter]
中。在循环结束时,users
中的所有条目都指向每次调用fgets()
都已覆盖的同一数组。
您应该使用strdup()
复制数组的内容:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[) {
char *users[51]; //given no more than 50 users
int r;
FILE *fp;
if (argc < 2) {
fprintf(stderr, "missing filename argument\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "cannot open file %s\n", argv[1]);
return 1;
}
char line[100];
int counter = 0;
while (counter < 50 && fgets(line, 100, fp) != NULL) {
char *username = strtok(line, ":");
if (username != NULL) {
users[counter] = strdup(username);
//counter increase for later
counter += 1;
}
}
users[counter] = NULL;
...
}
答案 2 :(得分:-1)
我想补充一下David的答案,即在使用strcpy()
之前,还应检查用户名字符串是否为空终止。我不记得strtok()
null是否终止,但您仍然不应该依赖它。
答案 3 :(得分:-1)
避免指针数组的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMELEN 16
#define MAXUSERS 51
typedef char uarray[MAXUSERS][NAMELEN];
int main() {
int i;
uarray * users = malloc(sizeof(uarray));
memset(users, 0, MAXUSERS*NAMELEN);
strncpy((*users)[0], "Alice", NAMELEN-1);
strncpy((*users)[1], "Bob", NAMELEN-1);
for (i=0; i<2; i++)
printf("%d: %s\n", i, (*users)[i]);
return 0;
}