循环遍历结构数组时打印的值不正确
Incorrect values printed when looping through and array of structs
我正在从一个文件中读取并将每一行的值保存到一个结构中。我保存的值是一个字符、一个字符串和两个整数。然后将每个结构保存到一个结构数组中。我想打印出这些值中的每一个以确保它们被正确保存,并且当我在 for 循环中访问数组中的每个结构时,除了字符串之外的所有内容都正确打印出来。我不明白为什么会这样。为了检查我在将字符串添加到给出预期输出的结构中后立即打印出字符串。只有当我尝试在我的 for 循环中访问这些字符串元素时,我才会得到不正确的输出。这是我的代码:
char wordFirstLetter;
struct BankAccount arrAccounts[20];
struct TransactionRequest arrTransactions[20];
int numAccounts = 0;
int numTransactions = 0;
int currAccountIndex = 0;
int currClient = 1;
while(fgets(line, sizeof(line),fp))
{
// We will be getting the words on each line using strtok()
//Gets the first word in the line
char *word = strtok(line, " ");
wordFirstLetter = word[0];
// Checks if the first letter of the line is 'a'
// If it is, then we know we are setting up the account
if(wordFirstLetter == 'a')
{
//not related
}
// Otherwise we are dealing with a client
else
{
while(word != NULL)
{
if(word[0] == 'c')
{
// Move on to the next word if we see that we are
// dealing with a client
word = strtok(NULL, " ");
}
else
{
// Create a structure to represent the current request
struct TransactionRequest transaction;
// Append the client number of the client doing the transaction
transaction.client = currClient;
// Append the type of transaction and move to next word
char *transType = word;
transaction.requestType = transType;
printf("This is the value of word: %s\n", word);
printf("%s\n", transaction.requestType);
word = strtok(NULL, " ");
// Append the account number that will be altered and move to next word
transaction.account = word[1] - '0';
word = strtok(NULL, " ");
// Append the amount for the transaction and move to next word
int transAmount = atoi(word);
transaction.amount = transAmount;
word = strtok(NULL, " ");
// Append this transaction to an array containing all transactions in the file
arrTransactions[numTransactions] = transaction;
numTransactions++;
}
}
// Each line represents a client, so when we are done with the
// line we move to the next client
currClient++;
}
}
for(int i = 0; i < numTransactions; i++)
{
struct TransactionRequest transaction = arrTransactions[i];
printf("This is the client number: %d\n", transaction.client);
printf("This is the request type: %s\n", transaction.requestType);
printf("This is the account to be accessed: %d\n", transaction.account);
printf("This is the amount: %d\n", transaction.amount);
printf("\n");
}
这是我正在使用的结构:
struct TransactionRequest
{
// ID if the client doing the transaction
int client;
// Type of transaction the client is doing
char *requestType;
// Account number of the account the client is dealing with
int account;
// Amount of money that is boing moved around
int amount;
};
打印这些字符串元素时,我在 for 循环中做错了什么吗?如果不是,为什么会出现这个问题。
word
在 while
循环之后超出范围,因此您的结构将包含指向无效数据的指针。即使您在 while 循环之前声明了 word
,TransactionRequest
的所有实例都将包含 word
的最新值,这可能不是预期的行为。如果您知道 requestType
不会超过一定长度,那么您可以在结构中使用固定长度的 char 数组。这样,无论您的结构实例是分配在堆栈还是堆上,requestType
数据对于每个实例都是唯一的,并且将 allocated/freed 与整个结构一起。
#define REQUEST_TYPE_MAX_LENGTH 256
struct TransactionRequest
{
// ID if the client doing the transaction
int client;
// Type of transaction the client is doing
char requestType[REQUEST_TYPE_MAX_LENGTH];
// Account number of the account the client is dealing with
int account;
// Amount of money that is boing moved around
int amount;
};
尽管如此,需要对您的代码进行重大重新设计。例如,您不能使用赋值将数据从 word
变量传输到 TranscationRequest
结构的 requestType
字段中。您将需要使用诸如 strncat
之类的函数以及手动空终止。
虽然不是严格相关,但我还要指出,TransactionRequest
中的帐号只能取0到9(含)之间的值,除非你的原始文件包含一些奇怪的ASCII字符。这是故意的吗?
我正在从一个文件中读取并将每一行的值保存到一个结构中。我保存的值是一个字符、一个字符串和两个整数。然后将每个结构保存到一个结构数组中。我想打印出这些值中的每一个以确保它们被正确保存,并且当我在 for 循环中访问数组中的每个结构时,除了字符串之外的所有内容都正确打印出来。我不明白为什么会这样。为了检查我在将字符串添加到给出预期输出的结构中后立即打印出字符串。只有当我尝试在我的 for 循环中访问这些字符串元素时,我才会得到不正确的输出。这是我的代码:
char wordFirstLetter;
struct BankAccount arrAccounts[20];
struct TransactionRequest arrTransactions[20];
int numAccounts = 0;
int numTransactions = 0;
int currAccountIndex = 0;
int currClient = 1;
while(fgets(line, sizeof(line),fp))
{
// We will be getting the words on each line using strtok()
//Gets the first word in the line
char *word = strtok(line, " ");
wordFirstLetter = word[0];
// Checks if the first letter of the line is 'a'
// If it is, then we know we are setting up the account
if(wordFirstLetter == 'a')
{
//not related
}
// Otherwise we are dealing with a client
else
{
while(word != NULL)
{
if(word[0] == 'c')
{
// Move on to the next word if we see that we are
// dealing with a client
word = strtok(NULL, " ");
}
else
{
// Create a structure to represent the current request
struct TransactionRequest transaction;
// Append the client number of the client doing the transaction
transaction.client = currClient;
// Append the type of transaction and move to next word
char *transType = word;
transaction.requestType = transType;
printf("This is the value of word: %s\n", word);
printf("%s\n", transaction.requestType);
word = strtok(NULL, " ");
// Append the account number that will be altered and move to next word
transaction.account = word[1] - '0';
word = strtok(NULL, " ");
// Append the amount for the transaction and move to next word
int transAmount = atoi(word);
transaction.amount = transAmount;
word = strtok(NULL, " ");
// Append this transaction to an array containing all transactions in the file
arrTransactions[numTransactions] = transaction;
numTransactions++;
}
}
// Each line represents a client, so when we are done with the
// line we move to the next client
currClient++;
}
}
for(int i = 0; i < numTransactions; i++)
{
struct TransactionRequest transaction = arrTransactions[i];
printf("This is the client number: %d\n", transaction.client);
printf("This is the request type: %s\n", transaction.requestType);
printf("This is the account to be accessed: %d\n", transaction.account);
printf("This is the amount: %d\n", transaction.amount);
printf("\n");
}
这是我正在使用的结构:
struct TransactionRequest
{
// ID if the client doing the transaction
int client;
// Type of transaction the client is doing
char *requestType;
// Account number of the account the client is dealing with
int account;
// Amount of money that is boing moved around
int amount;
};
打印这些字符串元素时,我在 for 循环中做错了什么吗?如果不是,为什么会出现这个问题。
word
在 while
循环之后超出范围,因此您的结构将包含指向无效数据的指针。即使您在 while 循环之前声明了 word
,TransactionRequest
的所有实例都将包含 word
的最新值,这可能不是预期的行为。如果您知道 requestType
不会超过一定长度,那么您可以在结构中使用固定长度的 char 数组。这样,无论您的结构实例是分配在堆栈还是堆上,requestType
数据对于每个实例都是唯一的,并且将 allocated/freed 与整个结构一起。
#define REQUEST_TYPE_MAX_LENGTH 256
struct TransactionRequest
{
// ID if the client doing the transaction
int client;
// Type of transaction the client is doing
char requestType[REQUEST_TYPE_MAX_LENGTH];
// Account number of the account the client is dealing with
int account;
// Amount of money that is boing moved around
int amount;
};
尽管如此,需要对您的代码进行重大重新设计。例如,您不能使用赋值将数据从 word
变量传输到 TranscationRequest
结构的 requestType
字段中。您将需要使用诸如 strncat
之类的函数以及手动空终止。
虽然不是严格相关,但我还要指出,TransactionRequest
中的帐号只能取0到9(含)之间的值,除非你的原始文件包含一些奇怪的ASCII字符。这是故意的吗?