我正在从文件中读取一行(char by char,使用fgetc()),其中所有字段(firstname,lastname,...)由;
分隔。我现在要做的是创建一个char**
,将所有字符添加到该字符并将;
替换为\0
,以便我有效地获取所有字段的列表。
这实际上可能吗?当我创建一个char **时,例如char ** buf = malloc(80)
我可以将它视为一维数组吗?如果malloc返回的内存是连续的?
修改
Sry,意味着将;
替换为\0
,机器人\n
。
编辑2
这段代码应该展示我打算做的事情(可能会稍微澄清一下):
int length = 80; // initial length char *buf = malloc(length); int num_chars = 0;
// handle malloc returning NULL
// suppose we already have a FILE pointer fp for (int ch = fgetc(fp); ch != EOF && ferror(fp) == 0; ch = fgetc(fp)) {
if (length == size) { // expand array if necessary
length += 80;
buf = realloc(buf, length);
// handle realloc failure
}
if (ch == ';') {
buf[num_chars] = '\0'; // replace delimiter by null-terminator
} else {
buf[num_chars] = ch; // else put char in buf
} }
// resize the buffer to chars read buf
= realloc(buf, num_chars);
// now comes the part where I'm quite unsure if it works / is possible
char **list = (char **)buf; // and now I should be able to handle it like a list of strings?
答案 0 :(得分:2)
是的,这是可能的。是的,您可以将其视为一维数组。是的,记忆是连续的。
但你可能想要:
char ** fields = malloc(sizeof(char *) * numFields);
然后你可以这样做:
// assuming `field` is a `char *`
fields[i++] = field;
答案 1 :(得分:1)
我现在要做的是创建一个char **,将所有字符添加到
您将分配一个char(char *)数组来存储字符,而不是char *(char **)数组。
当我创建一个char * 时,例如char * buf = malloc(80)我可以将它视为一维数组吗?如果malloc返回的内存是连续的?
是的,malloc总是返回连续的块。是的,您可以将其视为一维char*
(带80/sizeof char*
个元素)的数组。但是你需要为存储在这个数组中的每个字符串单独分配内存,或者创建另一个用于存储字符串数据的块,然后使用你的第一个数组来存储指向该块的指针。
(或其他东西;很多方法可以给这只猫上皮)
答案 2 :(得分:1)
你所描述的并不完全可能,但类似的东西是可能的。
更具体地说,示例char **list = (char **)buf;
的最后一行不符合您的要求。 char **list
表示* list指向的项目属于char*
类型,但*buf
的内容是字符。因此,不可能将一个变为另一个。
你应该明白char **
只是一个指针,它本身不能保留任何东西。但char **
可以是char *
数组的起始地址,每个char *
指向一个字段。
您必须使用第一个malloc为char *
数组分配空间(或者您也可以使用char *
而不是char**
的静态数组。您还必须为每个字段找到空间,可能为每个字段执行malloc并从初始缓冲区复制它。如果初始缓冲区在读取后未触及,也可以使用它来保存字段名称,但是如果你只是替换它;
的初始\n
,你将缺少尾随的0字符串终止符,你不能用两个字符替换一个字符。
下面是一个简单的例子,说明了可以做什么(删除了malloc部分,因为它没有为示例添加太多内容,并使其无用复杂,这是另一个故事):
#include <stdio.h>
#include <string.h>
main(){
// let's define a buffer with space enough for 100 chars
// no need to perform dynamic allocation for a small example like this
char buf[100];
const char * data = "one;two;three;four;";
// now we want an array of pointer to fields,
// here again we use a static buffer for simplicity,
// instead of a char** with a malloc
char * fields[10];
int nbfields = 0;
int i = 0;
char * start_of_field;
// let's initialize buf with some data,
// a semi-colon terminated list of strings
strcpy(buf, data);
start_of_field = buf;
// seek end of each field and
// copy addresses of field to fields (array of char*)
for (i = 0; buf[i] != 0; i++){
if (buf[i] == ';'){
buf[i] = 0;
fields[nbfields] = start_of_field;
nbfields++;
start_of_field = buf+i+1;
}
}
// Now I can address fields individually
printf("total number of fields = %d\n"
"third field is = \"%s\"\n",
nbfields, fields[2]);
}
答案 3 :(得分:1)
Helper Method可能希望将每个“字段”写入以空字符结尾的字符串。我不能说。你可以用strtok()来做到这一点。但是strtok()有问题 - 它会破坏原始字符串“fed”到它。
#define SPLIT_ARRSZ 20 /* max possible number of fields */
char **
split( char *result[], char *w, const char *delim)
{
int i=0;
char *p=NULL;
for(i=0, result[0]=NULL, p=strtok(w, delim); p!=NULL; p=strtok(NULL, delim), i++ )
{
result[i]=p;
result[i+1]=NULL;
}
return result;
}
void
usage_for_split(void)
{
char *result[SPLIT_ARRSZ]={NULL};
char str[]="1;2;3;4;5;6;7;8;9;This is the last field\n";
char *w=strdup(str);
int i=0;
split(result, w, ";\n");
for(i=0; result[i]!=NULL; i++)
printf("Field #%d = '%s'\n", i, result[i]);
free(w);
}