在C中将字符串拆分为标记 struct字符串{ 尺寸与长度; 分配的大小; 字符*数据; }; 字符串*strCreate(char*str){…} string*strSubstring(string*str,size\t pos,size\t len){…} char*strGet(字符串*str){ 返回str->data; } 大小\u t findFrist(字符串*str、字符what、大小\u t pos){ 用于(尺寸i=pos;ilength;++i){ 如果(str->data[i]==什么) 返回i; } 返回-1; } 字符串**strTokenizer(字符串*str){ 字符串**res; res=malloc(sizeof(char*)*90);//*90(tokennum) 对于(int i=0;i长度; string*token=strSubstring(str,first,second-first); 如果(*目标(令牌)!=“”) res[i]=令牌; 第一个=第二个+1; ++一,; } 返回res; } int main(){ string*fe=strCreate(“字符串\tof”); 字符串**r=strTokenizer(fe); 对于(int i=0;i

在C中将字符串拆分为标记 struct字符串{ 尺寸与长度; 分配的大小; 字符*数据; }; 字符串*strCreate(char*str){…} string*strSubstring(string*str,size\t pos,size\t len){…} char*strGet(字符串*str){ 返回str->data; } 大小\u t findFrist(字符串*str、字符what、大小\u t pos){ 用于(尺寸i=pos;ilength;++i){ 如果(str->data[i]==什么) 返回i; } 返回-1; } 字符串**strTokenizer(字符串*str){ 字符串**res; res=malloc(sizeof(char*)*90);//*90(tokennum) 对于(int i=0;i长度; string*token=strSubstring(str,first,second-first); 如果(*目标(令牌)!=“”) res[i]=令牌; 第一个=第二个+1; ++一,; } 返回res; } int main(){ string*fe=strCreate(“字符串\tof”); 字符串**r=strTokenizer(fe); 对于(int i=0;i,c,string,pointers,split,C,String,Pointers,Split,我想创建一个字符串标记器。当我想在main函数中打印字符串时,它不会打印\。另一件事是如何以正确的方式分配string**res。当我分配sizeof(char*)我看到的唯一方法是循环遍历字符串,但我只是想知道是否可以在标记器函数中不遍历字符串两次就进行分配 我不想使用strtok typedef struct string在.h文件中使用GCC 10.2.0和选项编译代码时: struct string { size_t length; size_t allocated;

我想创建一个字符串标记器。当我想在
main
函数中打印字符串时,它不会打印
\
。另一件事是如何以正确的方式分配
string**res
。当我分配
sizeof(char*)
我看到的唯一方法是循环遍历字符串,但我只是想知道是否可以在标记器函数中不遍历字符串两次就进行分配

我不想使用
strtok


typedef struct string
在.h文件中

使用GCC 10.2.0和选项编译代码时:

struct string {
    size_t length;
    size_t allocated;
    char* data;
};
    string* strCreate(char* str) {...}
string* strSubstring(string* str, size_t pos, size_t len) {...}
char* strGet(string* str) {
    return str->data;
}
size_t findFrist(string* str, char what, size_t pos) {
    for(size_t i = pos; i < str->length; ++i) {
        if(str->data[i] == what)
            return i;
    }
    return -1;
}
string** strTokenizer(string* str) {
    string** res;
    res = malloc(sizeof(char*)*90); //*90 (token num)
    for(int i=0; i<90; i++) //i<90 (token num)
        res[i] = malloc(sizeof(char)*100); //*100 (a token lenght)
    size_t first = 0;
    size_t i = 0;
    while(first < str->length) {
        int second = findFrist(str,' ',first);
        if(second == - 1)
            second = str->length;
        string* token = strSubstring(str,first, second - first);
        if(*strGet(token) != ' ')
            res[i] = token;
        first = second + 1;
        ++i;
    }
    return res;
}
int main() {
    string* fe = strCreate("A string \ tof");
    string** r = strTokenizer(fe);
    for(int i = 0; i < 4; ++i) {
        printf("%s",strGet(r[i]));
    }
    return 0;
}
我得到的信息是:

bs83.c:85:44:错误:未知转义序列:'\040'[-Werror]
85 | string*fe=strCreate(“字符串\tof”);
正如我在评论中所指出的,字符串
“A string\tof”
的格式不正确-您的编译器应该就此向您发出警告。如果您希望在字符串中使用反斜杠,您可以编写(例如),
“A string\\tof”
。反斜杠空格没有定义的含义;它可能被解释为一个空格。也许您应该将参数打印到
strCreate()
以验证这一点

您还需要在代码顶部附近放置
typedef struct string;
,以便使用C编译器(以及标题)进行编译

这里是您的代码的固定版本-由于我使用的编译选项,函数需要是
静态的
,或者在定义之前声明;我将它们设置为
静态的
,因为这是将它们设置为非
静态的唯一原因(IMO)如果它们是从另一个源文件访问的,那么它们将在头文件中声明。这可能适用于您的代码-这里提到了头文件

以下是固定代码:

gcc -O3 -g -std=c11 -Wall -Wextra -Werror …

注意在打印的字符串(和换行符)周围使用
[[[
]
)。这样可以更容易地识别尾随空格和嵌入的回车符以及其他各种错误。

您需要循环分配,但为什么要为每个结构分配100字节,而每个结构可能有12字节?或者如果其中的数据是动态分配的,为什么还要将它们作为动态分配的?除了lat之外呃,用一个我们甚至在这里看不到的函数来改写指针。这看起来很复杂,如果没有注释,你需要“<代码> TyPufFrEST String String;(或等价)),在顶部附近的某个地方,可以用C编译器编译代码而不是C++编译器。(您还可以将
First
修改为
First
并将
lenght
修改为
length
)显示未编译的代码不会获得布朗尼点数。请创建MCVE(-或MRE或现在使用的任何名称)或SSCCE()。如果不修改
struct string
typedef
,您的程序就无法编译,而且很少有函数缺少定义,如
strCreate
strSubstring
。最好提供最小的可编译性和可执行性,以便人们可以尝试在线etcNote,使字符串
成为“字符串\tof”
格式不正确-编译器应该就此向您发出警告。如果您希望在字符串中使用反斜杠,您可以编写(例如),
“a string\\tof”
。反斜杠空格没有定义的含义;它可能被解释为单个空格。也许您应该将参数打印到
strCreate()
以验证这一点。
/* SO 6537-9584 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct string string;

struct string
{
    size_t length;
    size_t allocated;
    char *data;
};

static
string *strCreate(char *str)
{
    string *s = malloc(sizeof(string));
    s->length = strlen(str);
    s->allocated = s->length * 2;
    s->data = (char *)malloc(s->allocated + 1);
    memcpy(s->data, str, s->length);
    s->data[s->length] = '\0';
    return s;
}

static
string *strSubstring(string *str, size_t pos, size_t len)
{
    string *s = malloc(sizeof(string));
    s->length = len;
    s->allocated = s->length * 2;
    s->data = (char *)malloc(s->allocated + 1);
    memcpy(s->data, &str->data[pos], s->length);
    s->data[s->length] = '\0';
    return s;
}

static
char *strGet(string *str)
{
    return str->data;
}

static
size_t findFirst(string *str, char what, size_t pos)
{
    for (size_t i = pos; i < str->length; ++i)
    {
        if (str->data[i] == what)
            return i;
    }
    return -1;
}

static
string **strTokenizer(string *str)
{
    string **res;
    res = malloc(sizeof(char *) * 90); // *90 (token num)
    for (int i = 0; i < 90; i++) // i<90 (token num)
        res[i] = malloc(sizeof(char) * 100); // *100 (a token length)
    size_t first = 0;
    size_t i = 0;
    while (first < str->length)
    {
        int second = findFirst(str, ' ', first);
        if (second == -1)
            second = str->length;
        string *token = strSubstring(str, first, second - first);
        if (*strGet(token) != ' ')
            res[i] = token;
        first = second + 1;
        ++i;
    }
    return res;
}

int main(void)
{
    string *fe = strCreate("A string \\ tof");
    string **r = strTokenizer(fe);
    for (int i = 0; i < 4; ++i)
    {
        printf("[[%s]]\n", strGet(r[i]));
    }
    return 0;
}
[[A]]
[[string]]
[[\]]
[[tof]]