在C中,我如何用分隔符分隔字符数组?或者操作字符串更好?有哪些好的C字符操作函数?
acruukt91#
#include<string.h> #include<stdio.h> int main() { char input[16] = "abc,d"; char *p; p = strtok(input, ","); if(p) { printf("%s\n", p); } p = strtok(NULL, ","); if(p) printf("%s\n", p); return 0; }
你可以看看这个程序。首先你应该使用strtok(input,“,”)。input是你想要拆分的字符串。然后你使用strtok(NULL,“,”)。如果返回值为true,你可以打印另一个组。
ttcibm8c2#
看看**strtok()。**strtok()不是一个可重入函数。strtok_r()是strtok()的可重入版本。下面是手册中的一个示例程序:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j; if (argc != 4) { fprintf(stderr, "Usage: %s string delim subdelim\n",argv[0]); exit(EXIT_FAILURE); } for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) { token = strtok_r(str1, argv[2], &saveptr1); if (token == NULL) break; printf("%d: %s\n", j, token); for (str2 = token; ; str2 = NULL) { subtoken = strtok_r(str2, argv[3], &saveptr2); if (subtoken == NULL) break; printf(" --> %s\n", subtoken); } } exit(EXIT_SUCCESS); }
示例运行,它对基于不同分隔符从前一个令牌获得的子令牌进行操作:
$ ./a.out hello:word:bye=abc:def:ghi = : 1: hello:word:bye --> hello --> word --> bye 2: abc:def:ghi --> abc --> def --> ghi
s3fp2yjn3#
一种选择是strtok示例:
char name[20]; //pretend name is set to the value "My name"
你想在两个单词之间的空格处拆分它
split=strtok(name," "); while(split != NULL) { word=split; split=strtok(NULL," "); }
iugsix8n4#
您可以简单地将分隔符替换为NULL字符,并将地址存储在新创建的NULL字符之后的新char* 指针中:
char* input = "asdf|qwer" char* parts[10]; int partcount = 0; parts[partcount++] = input; char* ptr = input; while(*ptr) { //check if the string is over if(*ptr == '|') { *ptr = 0; parts[partcount++] = ptr + 1; } ptr++; }
请注意,如果输入字符串包含的分隔符超过9个,则此代码当然不起作用。
5kgi1eie5#
我想出了这个。这似乎对我最有效。它转换一个数字字符串并将其拆分为整数数组:
void splitInput(int arr[], int sizeArr, char num[]) { for(int i = 0; i < sizeArr; i++) // We are subtracting 48 because the numbers in ASCII starts at 48. arr[i] = (int)num[i] - 48; }
zhte4eai6#
我就是这么做的。
void SplitBufferToArray(char *buffer, char * delim, char ** Output) { int partcount = 0; Output[partcount++] = buffer; char* ptr = buffer; while (ptr != 0) { //check if the string is over ptr = strstr(ptr, delim); if (ptr != NULL) { *ptr = 0; Output[partcount++] = ptr + strlen(delim); ptr = ptr + strlen(delim); } } Output[partcount++] = NULL; }
velaa5lx7#
另外,你可以在一些非常简单的场景中使用sscanf,例如当你确切知道字符串有多少个 * 部分 * 以及它由什么组成时。你也可以动态解析参数。不要将它用于用户输入,因为函数不会报告转换错误。示例:
sscanf
char text[] = "1:22:300:4444:-5"; int i1, i2, i3, i4, i5; sscanf(text, "%d:%d:%d:%d:%d", &i1, &i2, &i3, &i4, &i5); printf("%d, %d, %d, %d, %d", i1, i2, i3, i4, i5);
输出:1、22、300、4444、-5对于任何更高级的东西,strtok()和strtok_r()是您的最佳选择,如其他答案中所述。
bxfogqkk8#
mic_e的解决方案正是我要找的(谢谢)为了解析来自SIM7600模块的回复,包括来自AT+CGNSSINFO的GPS数据。在我创建的第一个方法中,我使用了忽略连续分隔符的strtok。由于来自AT+CGNSSINFO的数据可能有空字段(即课程)我的例程没有正确解析所有数据。我根据mic_e的解决方案改变了我的方法,现在我有了所需的结果,包括空字段。
char* parts[16]; // change according to total expected fields char* split2(char* input, char delimiter, int element, int length = 0){ int partcount = 0; parts[partcount++] = input; char* ptr = input; while (*ptr) { //check if the string is over if (*ptr == delimiter) { *ptr = 0; parts[partcount++] = ptr + 1; } ptr++; } if (length != 0) { parts[element][length] = '\0'; } return parts[element]; } // TEST char TEST[85] = { "3,04,00,00,ddmm.mmmmmm,N,dddmm.mmmmmm,E,210323,133128.0,999.9,0.0,,14.3,2.2,14.1" }; for (int i = 0; i < 16; i++) { //Serial.print(i); Serial.print("\t"); Serial.println(parts[i]); Serial.print(i); Serial.print("\t"); Serial.println(split2(TEST,',',i)); }
8条答案
按热度按时间acruukt91#
你可以看看这个程序。首先你应该使用strtok(input,“,”)。input是你想要拆分的字符串。然后你使用strtok(NULL,“,”)。如果返回值为true,你可以打印另一个组。
ttcibm8c2#
看看**strtok()。**strtok()不是一个可重入函数。
strtok_r()是strtok()的可重入版本。下面是手册中的一个示例程序:
示例运行,它对基于不同分隔符从前一个令牌获得的子令牌进行操作:
s3fp2yjn3#
一种选择是strtok
示例:
你想在两个单词之间的空格处拆分它
iugsix8n4#
您可以简单地将分隔符替换为NULL字符,并将地址存储在新创建的NULL字符之后的新char* 指针中:
请注意,如果输入字符串包含的分隔符超过9个,则此代码当然不起作用。
5kgi1eie5#
我想出了这个。这似乎对我最有效。它转换一个数字字符串并将其拆分为整数数组:
zhte4eai6#
我就是这么做的。
velaa5lx7#
另外,你可以在一些非常简单的场景中使用
sscanf
,例如当你确切知道字符串有多少个 * 部分 * 以及它由什么组成时。你也可以动态解析参数。不要将它用于用户输入,因为函数不会报告转换错误。示例:
输出:
1、22、300、4444、-5
对于任何更高级的东西,strtok()和strtok_r()是您的最佳选择,如其他答案中所述。
bxfogqkk8#
mic_e的解决方案正是我要找的(谢谢)为了解析来自SIM7600模块的回复,包括来自AT+CGNSSINFO的GPS数据。在我创建的第一个方法中,我使用了忽略连续分隔符的strtok。由于来自AT+CGNSSINFO的数据可能有空字段(即课程)我的例程没有正确解析所有数据。我根据mic_e的解决方案改变了我的方法,现在我有了所需的结果,包括空字段。