char* 在struct中为什么会这样

问题描述

我希望把一个文本文件里面的内容读出来,但是不知道为什么读取的那一行存放到自己自定义的struct类型的char *类型中总是把前面的读取的char *给内容给修改掉。出问题的地方我用注释标出来了

相关代码


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define SIZE 100
#define QUEUE_SIZE 100
#define TRUE 1
#define FALSE 0
typedef int bool;

struct Customer
{
    char *name;
    int arrivedTime;
    int priority;
    int age;
    int requireTime;
};

struct Queue
{
    struct Customer customers[QUEUE_SIZE];
    int size;
};

bool addCustomer(struct Queue* queue,struct Customer customer) {
    if (queue->size >= QUEUE_SIZE) {
        return FALSE;
    }
    else {
        queue->customers[queue->size] = customer;
        queue->size++;
        return TRUE;
    }
}

struct Customer getCustomer(struct Queue* queue,int index) {
    return queue->customers[index];
    for (int i = index; i < queue->size-1; i++) {
        queue->customers[i] = queue->customers[i + 1];
    }
    queue->size--;
}

int main() {
    struct Queue queue;
    queue.size = 0;
    FILE * file=fopen("C:\\Users\\zjb52\\Desktop\\cs\\sample-input.txt", "r");
    if (file == NULL) {
        printf("File not found");
    }
    else {
        char buffer[SIZE];
        while(fgets(buffer, SIZE, file) != NULL) {
            struct Customer customer;
                        
            //问题出现在这里,第二次循环的时候读取的内容是s1,但是queue里面本是s0也会变成s1
            customer.name = strtok(buffer, " ");
            customer.arrivedTime = atoi(strtok(NULL, " "));
            customer.priority = atoi(strtok(NULL, " "));
            customer.age = atoi(strtok(NULL, " "));
            customer.requireTime = atoi(strtok(NULL, " "));
            addCustomer(&queue, customer);    
        }        
    }
    fclose(file);
    system("pause");
    return 0;
}

sample-input.txt

s0 0 3 0 10
s1 0 6 0 20
s2 0 5 0 11
s3 0 6 0 20
s4 67 2 0 25
s5 5 4 0 1
s6 0 2 0 5
s7 0 4 0 28
s8 0 3 0 20
s9 45 5 0 6
s10 103 3 0 2

你期待的结果是什么?实际看到的错误信息又是什么?

while循环中customer.name = strtok(buffer, " ");我期望的结果是读取之后queue中customer.name应该是s0,s1,s2....s9,s10,但是结果却都是s10。为什么struct里面的char *类型的name会这样?我该怎么改呢?谢谢啦

阅读 3.3k
3 个回答

每一次while循环里定义的*char都是同一个地址,所以数据被覆盖掉了

测试代码,gcc编译,Ubuntu运行

#include<stdio.h>
#include<string.h>
typedef struct student{
  char *name;
  char num;
}student;
int main()
{ 
  char i = 0;
  while(i < 10){
  student xie;
    xie.name = &i;
    xie.num = i;
    printf("0x%p\n",xie.name);
    printf("%d\n",xie.num);
    i++;
  }

}

运行结果:

0x0x7ffc7f2ca04f
0
0x0x7ffc7f2ca04f
1
0x0x7ffc7f2ca04f
2
0x0x7ffc7f2ca04f
3
0x0x7ffc7f2ca04f
4
0x0x7ffc7f2ca04f
5
0x0x7ffc7f2ca04f
6
0x0x7ffc7f2ca04f
7
0x0x7ffc7f2ca04f
8
0x0x7ffc7f2ca04f
9

因为 strtok 会修改原字符串, strok 返回的值总是 buffer, 所以你的所有 name 字段都指向 buffer. 而 strok 每次都在修改这个 buffer.

char temp[SIZE];
customer.name = strtok(strncpy(temp, buffer, SIZE), " ");

你给的代码不能解决问题,谢谢你给出的原因,让我知道问题出在哪里了,
我把Customer的name由char*换成了char[]
while循环的代码做了如下修改:

char buffer[SIZE];
        
while(fgets(buffer, SIZE, file) != NULL) {
            
    struct Customer customer;
    strcpy(customer.name,strtok(buffer, " "));
    customer.arrivedTime = atoi(strtok(NULL, " "));
    customer.priority = atoi(strtok(NULL, " "));
    customer.age = atoi(strtok(NULL, " "));
    customer.requireTime = atoi(strtok(NULL, " "));
    addCustomer(&queue, customer);    
    }        
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进