[英]How can I display integer that has 2 or more digits as a string?
[英]I have a string str which has two array (can be more) that I would like to convert to integer arrays in C
例如,输入:
c[] = "[1,2,3][5,7,8]"
输出:
a = [1,2,3] //of type int a[]
b = [5,7,8] //of type int b[]
我尝试使用strtok删除“]”。 但是,当我下次使用strtok时,我将无法使用它。 如果我尝试打印输出,我得到
[1,2,3
[1
2
3
代替
[1,2,3
[1
2
3
[5,7,8
[5
7
8
到目前为止我拥有的代码
char c[] = "[1,2,3][5,7,8]";
char *token = strtok(c, "]");
for (token; token != NULL ; token = strtok(NULL, "]")){
puts(token);
char *comma = strtok(c, ",");
for (comma; comma != NULL; comma = strtok(NULL, ",")){
puts(comma);
}
}
您的问题是,strtok有内存。 第一次传递字符串时,只要您将NULL
作为第一个参数传递,它就会被记住并反复使用。
但是,在循环中,您可以使用参数再次调用strtok。 因此,这个新的字符串(仅是第一个标记)被放置在strtok的内存中,并且在内部循环中对其进行了完全处理之后,在外部循环中没有剩下要标记化的内容。
看一下该线程 ,它更详细地说明了strtok的工作方式。
但是,您很幸运:strtok正在处理您首先在原处传递的字符串(这就是为什么您必须传递要标记为char*
的字符串,但分隔符可以是const char*
)。 因此,您可以执行以下操作:
char c[] = "[1,2,3][5,7,8]";
char* next = c;
char* token;
while((token = strtok(next, "]")))
{
puts(token);
next += strlen(token) + 1; // move next behind the token
token = strtok(token, ",");
do
{
puts(token);
}
while((token = strtok(NULL, ",")));
}
如果您想知道多余的括号,可以防止在编译器中出现警告(“可能的分配而不是比较”)。
该解决方案具有两个strtok_s
嵌套循环,因为strtok
不可重入。 这是MSVC,某些系统实现了类似的strtok_r
。
我已经按照您的问题的顶部创建了输出,可以将其修改为适合其他输出,这不是很清楚。 在这种情况下,并不需要两个嵌套循环,但是您后面的示例通过分解逗号输入而使问题变得困惑。
#include <stdio.h>
#include <string.h>
int main(void) {
char c[] = "[1,2,3][5,7,8]";
char *tok1 = NULL;
char *tok2 = NULL;
char *end1 = NULL;
char *end2 = NULL;
int comma = 0;
char identifier = 'a';
tok1 = strtok_s(c, "[]", &end1);
while(tok1 != NULL) { // outer loop splitting [bracket] parts
printf("%c = [", identifier);
comma = 0; // control comma output
tok2 = strtok_s(tok1, ",", &end2);
while(tok2 != NULL) { // inner loop splitting ,comma, parts
if(comma) { // check if comma required
printf(",");
}
printf("%s", tok2);
comma = 1; // a comma will be needed
tok2 = strtok_s(NULL, ",", &end2);
}
printf("] //of type int %c[]\n", identifier);
identifier++;
tok1 = strtok_s(NULL, "[]", &end1);
}
return 0;
}
您无需在[方括号]中进行检查的简单程序是
#include <stdio.h>
#include <string.h>
int main(void) {
char c[] = "[1,2,3][5,7,8]";
char *tok = NULL;
char identifier = 'a';
tok = strtok(c, "[]");
while(tok != NULL) {
printf("%c = [%s] //of type int %c[]\n", identifier, tok, identifier);
identifier++;
tok = strtok(NULL, "[]");
}
return 0;
}
在这两种情况下,输出均为:
a = [1,2,3] //of type int a[]
b = [5,7,8] //of type int b[]
EDIT修改了第二个示例,以根据上面OP最近的评论提供输出。
#include <stdio.h>
#include <string.h>
int main(void) {
char c[] = "[1,2,3][5,7,8]";
char *tok = NULL;
char identifier = 'a';
tok = strtok(c, "[]");
while(tok != NULL) {
printf("int %c[] = { %s };\n", identifier, tok, identifier);
identifier++;
tok = strtok(NULL, "[]");
}
return 0;
}
程序输出:
int a[] = { 1,2,3 };
int b[] = { 5,7,8 };
如果要将字符串数字字符串转换为整数值数组(每个值一个字符)(或在任何字符数字前允许-
表示数组的负值 ),则最好编写一个简单的步骤通过字符串并手动执行转换。
下面是使用字符串的数组索引的示例。 您可以轻松地将数组索引符号更改为指针符号,这对于某些人来说更直观。
#include <stdio.h>
#include <string.h>
size_t str2arr (char *d, size_t max, char *s, size_t *ofs);
int main (int argc, char **argv) {
char c[] = "[1,2,3][5,7,8]";
char *p = argc > 1 ? argv[1] : c;
size_t i, offset = 0, na = 0, nb = 0, nchr = strlen (p);
char a[nchr], b[nchr];
memset (a, 0, nchr * sizeof *a); /* zero each VLA */
memset (b, 0, nchr * sizeof *b);
na = str2arr (a, nchr, p, &offset); /* convert first segment */
nb = str2arr (b, nchr, p + offset, &offset); /* convert second segment */
for (i = 0; i < na; i++) /* output results */
printf (" a[%2zu] : % d\n", i, a[i]);
putchar ('\n');
for (i = 0; i < nb; i++)
printf (" b[%2zu] : % d\n", i, b[i]);
putchar ('\n');
return 0;
}
/** convert a string of characters to an array of values
* including accounting for negative values. the destination
* index `di` returns the number of characters conversions, the
* offset of the next segment within 's' is updated in pointer 'ofs'
*/
size_t str2arr (char *d, size_t max, char *s, size_t *ofs)
{
if (!d || !s || !*s) return 0; /* validate input */
size_t di = 0, neg = 0;
register size_t si = 0;
for (; di < max && s[si]; si++, di++) { /* for each character */
if (s[si] == ']') break;
while (s[si] && (s[si] < '0' || ('9' < s[si]))) { /* if not digit */
if (s[si] == '-') neg = 1; /* if '-' sign, set flag */
else neg = 0; /* clear if not last before digit */
si++;
}
if (!s[si]) break; /* validate not end of string */
d[di] = neg ? -(s[si] - '0') : s[si] - '0'; /* convert to digit */
neg = 0; /* reset flag */
}
*ofs = si + 1; /* update offset before return */
return di; /* return number of conversions */
}
使用/输出示例
$ ./bin/str2arr
a[ 0] : 1
a[ 1] : 2
a[ 2] : 3
b[ 0] : 5
b[ 1] : 7
b[ 2] : 8
$ ./bin/str2arr "[1,2,3,4][5,6,-5,7,-1,8,9,2]"
a[ 0] : 1
a[ 1] : 2
a[ 2] : 3
a[ 3] : 4
b[ 0] : 5
b[ 1] : 6
b[ 2] : -5
b[ 3] : 7
b[ 4] : -1
b[ 5] : 8
b[ 6] : 9
b[ 7] : 2
仔细研究一下,将此方法与其他答案进行比较。 在C语言中,您可以根据自己的需要对数据的解析方式进行精细控制。 如果您不需要处理负值 ,那么实现会更加简单。 如果您有任何疑问,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.