如何在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); } }