C - 为什么 char 数组只返回放入其中的最后一个值?

标签 c

我正在用 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;

最佳答案

strtok 是一个非常令人困惑的函数:

  • 它修改它接收到的指针的数组
  • 它返回一个指向该数组元素的指针。
  • 它保持内部状态,使其不可重入且非线程安全。

因此用户名指向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;

    ...
}

关于C - 为什么 char 数组只返回放入其中的最后一个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55751187/

相关文章:

c - 结构不工作,得到垃圾输出

c - 如何从一组数字(不是范围)中生成随机数

c - 为什么 printf 不能正确显示我的数组?

c - 第二个输入 char* 造成无限循环

c - #define 宏用于 C 中的调试打印?

C - 获取字符串的指针地址

c - 警告 : X may be used uninitialized in this function

c - 汇编代码和 Switch 语句案例

c - 如何在 C 中使用 try-catch(或 C 中的等效项)

c - C中lstat fstat和stat的区别