如何在C中使用malloc和realloc读取和存储任意长度的字符串?

我有一个结构

typedef struct store { char name[11]; int age; } store; 

和一个主要function(下面是它的一部分):

 int main() { int i=0; int inputs; char line[100]; char name[11]; char command[11]; store read[3000]; while(i < 3000 && gets(line) != NULL) { int tempage; inputs = sscanf(line, "%10s %10s %d", command, name, &tempage); if (inputs == 3) { if (strcmp(command, "register") == 0) { strncpy(read[i].name, name,10); read[i].age = tempage; i++; .... 

我需要修改它,以便它可以读取任意长度的行,并使用malloc和realloc存储行中的名称,该行也是任意长度的字符串。

我该怎么办呢?

您需要做的是以较小的增量读取行,并随时调整缓冲区的大小。

作为一个例子(没有测试,也没有特别优雅的意思,只是一个例子):

 char *readline(FILE *f) { char *buf = NULL; size_t bufsz = 0, len = 0; int keep_going = 1; while (keep_going) { int c = fgetc(f); if (c == EOF || c == '\n') { c = 0; // we'll add zero terminator keep_going = 0; // and terminate the loop afterwards } if (bufsz == len) { // time to resize the buffer. // void *newbuf = NULL; if (!buf) { bufsz = 512; // some arbitrary starting size. newbuf = malloc(bufsz); } else { bufsz *= 2; // issue - ideally you'd check for overflow here. newbuf = realloc(buf, bufsz); } if (!newbuf) { // Allocation failure. Free old buffer (if any) and bail. // free(buf); buf = NULL; break; } buf = newbuf; } buf[len++] = c; } return buf; } 

将名称[11]更改为* name; 每次使用malloc为此分配内存。

顺便说一下, register是C语言中的关键字。 你不能像你一样使用它!

我想你要找的是:

 char* name; name = (char*)malloc(sizeof(char)); 

这种替代方法类似于@ asveikau,但通过复制堆栈来节省使用malloc()。

请不要用它来做作业答案。

 #include  #include  #include  char * slurponeline(FILE *f, int s) { const int size = 4096; char buffer[size]; char * r; int c,i=0; while( i=0 && c!='\n')) buffer[i++]=c; if (0 == s && 0 == i) return 0; r = (size==i)? slurponeline(f,s+size):malloc(s+i); memcpy(r+s,buffer,i); return r; } int main(int argc, char ** argv) { FILE * f = fopen(argc>1?argv[1]:"a.out","rb"); char * a,*command,*commandend,*name,*nameend; int age; while (a = slurponeline(f,0)) { char * p = a; while (*p && *p == ' ') ++p; // skip blanks. command = p; while (*p && *p != ' ') ++p; // skip non-blanks. commandend = p; while (*p && *p == ' ') ++p; // skip blanks. name = p; while (*p && *p != ' ') ++p; // skip non-blanks. nameend = p; while (*p && *p == ' ') ++p; // skip blanks. age = atoi(p); *commandend=0; *nameend=0; printf("command: %s, name: %s, age: %d\n",command,name,age); free(a); } }