【发布时间】:2016-01-08 03:56:11
【问题描述】:
我正在尝试使用fscanf 在结构中分配一个字符串,
我试过这个:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <Windows.h>
#include <string.h>
typedef struct _SPerson {
char *name;
char *surname;
char *id;
char *telephone;
}SPerson;
void main (void) {
unsigned int ne;
SPerson Archive[1000];
Load(Archive,&ne);
}
int Load(SPerson Archive[],unsigned int *ne) {
int k,i=0;
char s[4][20];
FILE *f;
f = fopen("archive.txt","r");
if(f==0) return 0;
while((k=fscanf(f,"%s %s %s %s",s[0],s[1],s[2],s[3]))==4) {
Archive[i].id = (char*) malloc( sizeof(char) *strlen(s[0]));
Archive[i].id =s[0];
Archive[i].name = (char*) malloc( sizeof(char) *strlen(s[1]));
Archive[i].name = s[1];
Archive[i].surname = (char*) malloc( sizeof(char) *strlen(s[2]));
Archive[i].surname = s[2];
Archive[i].telephone = (char*) malloc( sizeof(char) *strlen(s[3]));
Archive[i].telephone =s[3];
i++;
}
*ne = i;
fclose(f);
return 1;
}
也许在我的脑海中它是正确的,但是在加载数据时出现了问题,那么这是动态读取字符串的正确且清晰的方法吗?
我想用fgets,但是我的字符串是用空格隔开的,所以我需要实现另一个函数,split。谁能帮帮我?
【问题讨论】:
-
永远不要使用
scanf函数,它们按设计被破坏了。你想要fgets+strtok+strdup。另外,sizeof(char)根据定义是 1,所以永远不要写它。 -
您是否收到任何错误或警告? ??
-
输入文件的示例显示它是如何分隔的将有所帮助。如果所有行都包含相同的字段集,则只需几行。
-
您所有的内存分配都太短了 1 个字节(您需要分配
strlen(name)+1字节)。然后使用赋值而不是strcpy()泄漏内存。此外,您不断地覆盖相同的变量,因此所有数据最终看起来就像读取的最后一行。您没有确保格式字符串没有缓冲区溢出。您应该检查您的scanf()版本是否足够类似于 POSIX 以支持%ms,其中scanf()为您分配内存 - 但您传递的是char **而不是char *。 -
另外,
Archive[i].name = s[1];并没有做你认为的那样......
标签: c string allocation scanf