我想使用函数修改作为结构一部分的字符串的内容。问题是,当我在函数外部打印字符串时,没有输出,但如果我在函数内部打印字符串,则输出为 FOO,这是正确的输出。我在我认为有问题的行中添加了注释。
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ACCOUNT_NUM_LEN 15
#define NAME_LEN 255
#define PIN_LEN 4
#define BAL_LEN 50
typedef struct account
{
// account info
int account_num[ACCOUNT_NUM_LEN];
int pin[PIN_LEN];
float bal;
// name of the account owner
char* fname;
char* lname;
// link to next account
struct account *next;
}
account;
account* root;
int num_of_accounts;
bool init(void)
{
// example
char account_inf[80] = "FOO|BAZ|123123000012300|1234|5000.00";
const char delimiter[2] = "|";
// initialize root and set number of accounts to 0
root = NULL;
num_of_accounts = 0;
// get the first token
char* token = strtok(account_inf, delimiter);
// create a new user each line
account* new_user = malloc(sizeof(account));
if (new_user == NULL)
return false;
// initialize new user info
new_user->lname = NULL;
new_user->fname = NULL;
new_user->next = NULL;
// walk through other tokens
int info = 0;
while (token != NULL)
{
// filter info
if (info == 0)
{
new_user->lname = token; // problem
info++;
}
else if (info == 1)
{
new_user->fname = token; // problem
info++;
}
else if (info == 2)
{
for (int i = 0; i < ACCOUNT_NUM_LEN; i++)
new_user->account_num[i] = token[i] - '0';
info++;
}
else if (info == 3)
{
for (int i = 0; i < PIN_LEN; i++)
new_user->pin[i] = token[i] - '0';
info++;
}
else if (info == 4)
{
new_user->bal = atof(token);
info++;
}
token = strtok(NULL, delimiter);
}
root = new_user;
printf("%s\n", root->lname);
printf("%s\n", root->fname);
for (int i = 0; i < ACCOUNT_NUM_LEN; i++)
printf("%d", root->account_num[i]);
printf("\n");
for (int i = 0; i < PIN_LEN; i++)
printf("%d", root->pin[i]);
printf("\n");
printf("%f\n\n", root->bal);
return true;
}
int main(void)
{
// load up all accounts. exit if no account is found or made
if (!init())
return 1;
printf("%s\n", root->lname);
printf("%s\n", root->fname);
for (int i = 0; i < ACCOUNT_NUM_LEN; i++)
printf("%d", root->account_num[i]);
printf("\n");
for (int i = 0; i < PIN_LEN; i++)
printf("%d", root->pin[i]);
printf("\n");
printf("%f\n\n", root->bal);
return 0;
}
最佳答案
您应该阅读manpage for strtok
。该函数返回指向原始字符串的指针。由于您在堆栈上分配输入字符串,因此当您从 init
函数返回时,它会被释放。当您在 main
中对 printf
进行后续调用时,您将覆盖堆栈上的旧字符串。为了说明这一点,您可以在输入字符串前面添加一堆填充,这样它就不会被 printf
调用覆盖:
bool init(void)
{
// adding this padding should make the program print the desired output
char padding[1024];
// example
char account_inf[80] = "FOO|BAZ|123123000012300|1234|5000.00";
// . . .
但是,这并不是真正的修复,因为您仍在使用已从堆栈中弹出的内存。幸运的是,要真正修复它,您所要做的就是对输入字符串进行堆分配:
const char INPUT_STR[] = "FOO|BAZ|123123000012300|1234|5000.00";
bool init(void)
{
// example
char * account_inf = malloc(sizeof(INPUT_STR));
strcpy(account_inf, INPUT_STR);
// . . .
或者,您可以将字符串放入静态内存中(即,将 INPUT_STR
中的 const
去掉,然后使用它),但如果您这样做,请记住strtok
将修改存储在静态内存中的原始字符串,因此您以后无法再次使用它。
关于c - 使用函数修改结构体中字符串的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19395114/