我在使用C语言向数组添加结构时遇到问题。我认为这是因为我可能没有正确使用指针。
我有一些结构,语法如下:
struct account
{
int num;
char* fname;
char* lname;
char* pin;
double bal;
};
并且在我的main函数中我希望有一个for循环,它在经过并将我的struct的变量设置为某个东西之后为数组添加了一个struct。到目前为止,这是我的完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct account
{
int num;
char* fname;
char* lname;
char* pin;
double bal;
};
void split_str (struct account *a,char *line)
{
int i = 0; //incrementer to tell what we are looking at: num, fname, lname, pin, or bal
int acc_num; //temp vals to store acc_num casting and balance casting
double bal;
char * str;
str = strtok(line, " ");
while (str!= NULL){
switch(i){
case 0:
acc_num = atoi(str);
a->num = acc_num;
acc_num = 0;
break;
case 1:
a->fname = str;
break;
case 2:
a->lname = str;
break;
case 3:
a->pin = str;
break;
case 4:
bal = atof(str);
a->bal = bal;
bal = 0;
break;
}
str = strtok (NULL, " ");
i++; //increment because we want to look through all 5 possibilities of vars
}
}
int main()
{
FILE *fh = fopen("account_info.txt", "r");
struct account accts[100];
if (fh != NULL)
{
char line[256];
for (int i=0; fgets(line, sizeof line, fh) != NULL; i++)
{
split_str(&accts[i], line);
}
}
fclose(fh);
for (int i=0; i<3; i++)
{
printf("%s %s index: %i\n", accts[i].fname, accts[i].lname, i);
}
}
此代码与account_info.txt文件一起使用。所有该文件包含的每行一个“帐户”用空格“”字符分隔。例如:
123456 Jane Doe 1234 250.50
123457 John Smith 2222 12.34
123458 Sally Jones 9999 321.79
问题与我当前的代码一样,它似乎确实在数组中输入了一个结构,但是它做错了。当我在我的代码的第二个for循环中使用print语句运行它时,我的代码向我吐出了这些内容:
Sally Jones index: 0
Sally index: 1
Sally Jones index: 2
对于为什么采用这种方式行事的任何帮助都将非常感激。
答案 0 :(得分:2)
在split_str()中,您要指定指针(位置) 帐户中悬挂的本地字符串 该函数已被保留(因为str指针在 split_str被解除分配并可能在任何地方重用 稍后代码中的其他点...)。
确保收集到的信息 你需要split_str幸存下来的函数调用 分配内存到fname(或lname或pin或任何 在函数中使用其他指针),然后使用一些memcpy 或其他方法来复制str指向的信息 进入a。指向的结构。
答案 1 :(得分:0)
问题是main中只有一个line
实例,因此所有数组指针都指向那一行以及它在最后fgets
之后包含的内容。
sscanf可用于解析整数和双精度。使用%n
说明符,可以捕获名称和引脚的起始和停止索引。 %*s
说明符将读取并丢弃字符串,因为它们的长度尚不清楚。一旦知道了起始和终止索引,就可以分配内存并使用memcpy
复制字符串。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct account
{
int num;
char* fname;
char* lname;
char* pin;
double bal;
};
int split_str (struct account *a,char *line)
{
int startfn = 0;
int stopfn = 0;
int startln = 0;
int stopln = 0;
int startpin = 0;
int stoppin = 0;
if ( ( 2 == sscanf ( line, "%d %n%*s%n %n%*s%n %n%*s%n %lf"
, &(a->num)
, &startfn
, &stopfn
, &startln
, &stopln
, &startpin
, &stoppin
, &(a->bal)))) {
if ( ( a->fname = malloc ( ( stopfn - startfn) + 1)) == NULL) {
fprintf ( stderr, "problem malloc\n");
exit ( 1);
}
memcpy ( a->fname, &line[startfn], stopfn - startfn);
a->fname[stopfn - startfn] = '\0';
if ( ( a->lname = malloc ( ( stopln - startln) + 1)) == NULL) {
fprintf ( stderr, "problem malloc\n");
exit ( 1);
}
memcpy ( a->lname, &line[startln], stopln - startln);
a->lname[stopln - startln] = '\0';
if ( ( a->pin = malloc ( ( stoppin - startpin) + 1)) == NULL) {
fprintf ( stderr, "problem malloc\n");
exit ( 1);
}
memcpy ( a->pin, &line[startpin], stoppin - startpin);
a->pin[stoppin - startpin] = '\0';
return 1;
}
return 0;
}
int main()
{
FILE *fh = fopen("account_info.txt", "r");
struct account accts[100];
int loaded = 0;
if (fh != NULL)
{
char line[256];
for (int i=0; fgets(line, sizeof line, fh) != NULL; i++)
{
if ( split_str(&accts[i], line)) {
loaded++;
}
}
}
fclose(fh);
for (int i=0; i<loaded; i++)
{
printf("%s %s index: %i\n", accts[i].fname, accts[i].lname, i);
}
for (int i=0; i<loaded; i++)//free allocated memory
{
free ( accts[i].fname);
free ( accts[i].lname);
free ( accts[i].pin);
}
}