我正在尝试对字符串数组进行标记,但是,我的程序会继续打印这些奇怪的字符。我相信它与null终止我的字符串有关。如果这是问题,那么我该怎么做才能解决它?
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
char* s[] = { "12, 34, 56, 78", "82.16, 41.296",
"2, -3, 5, -7, 11, -13, 17, -19",
"9.00009, 90.0009, 900.009, 9000.09, 90000.9" };
char *token = strtok(s, ", ");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ", ");
}
return 0;
}
这是输出的照片。
谢谢
答案 0 :(得分:2)
你要么搞砸了s
的声明(最有可能是你剩下的代码),要么你搞砸了s
的声明并在s
上调用了strtok(这是一个指针指向char *的数组,包含指向字符串文字的指针,如图所示。)
您似乎确实希望char s[]
作为您的声明。这将揭示初始化中几个缺少 和几个无关 ','
的问题。要将s
声明为 array-of-char ,并按逗号分隔值列表进行初始化,您基本上需要
char s[] = { "12, 34, 56, 78, ...., 9000.09, 90000.9" };
初始化中不要求您只有一组引号(".."
),但是您要从字符串中标记的每个值都必须包含一个逗号(除了最后一个值)。您可以按如下方式声明和初始化s
:
char s[] = { "12, 34, 56, 78," "82.16, 41.296,"
"2, -3, 5, -7, 11, -13, 17, -19,"
"9.00009, 90.0009, 900.009, 9000.09, 90000.9" };
在这种情况下,代码的其余部分工作正常,产生以下输出:
$ ./bin/strtok_arr
12
34
56
78
82.16
41.296
2
-3
5
-7
11
-13
17
-19
9.00009
90.0009
900.009
9000.09
90000.9
如果你的意图是创建一个指针数组到char * (例如char *s[]
),那么你必须重做声明和代码的其余部分,因为(1)您没有将字符指针传递给strtok
;和(2)strtok
修改传递的字符串,调用strtok
,同时传递字符串文字只是明显错误 - 并保证 SegFault
如果您有任何问题,请与我们联系。
作为指向char *的指针数组
如果您需要在s
中找到每个字符串的卑鄙或平均值,请从评论中选择s
是一个指向char *的指针数组。正如评论中所述,您无法初始化char *s[]
以包含{ "stuff", "morestuff", ... }
,因为"stuff"
和"morestuff"
是字符串文字,并且在大多数情况下都会创建在只读内存中。由于strtok
修改了原始字符串,因此您将尝试修改只读内存,其中9次中有9次会导致友好的分段错误(不是好)。
然而,您可以简单地将单个字符串创建为字符数组,然后从字符数组创建s
,例如:
char s1[] = "12, 34, 56, 78",
s2[] = "82.16, 41.296",
s3[] = "2, -3, 5, -7, 11, -13, 17, -19",
s4[] = "9.00009, 90.0009, 900.009, 9000.09, 90000.9",
*s[] = { s1, s2, s3, s4 };
然后,您可以通过使用strtok
对每个字符串进行标记,然后将每个值转换为double
,同时收集每个字符串的sum
和average
来完成代码。 e.g。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main (void)
{
char s1[] = "12, 34, 56, 78",
s2[] = "82.16, 41.296",
s3[] = "2, -3, 5, -7, 11, -13, 17, -19",
s4[] = "9.00009, 90.0009, 900.009, 9000.09, 90000.9",
*s[] = { s1, s2, s3, s4 };
size_t i, idx = 0, n = sizeof s/sizeof *s;
double avg[n];
for (i = 0; i < n; i++) {
double sum = 0.0;
size_t nval = 0;
char *token = strtok (s[i], ", ");
while (token != NULL) {
sum += strtod (token, NULL);
nval++;
printf (" %8s, sum : %9.2lf\n", token, sum);
token = strtok (NULL, ", ");
}
printf ("----------------------------\n");
printf (" average : %9.2lf\n\n", (avg[idx++] = sum/nval));
}
return 0;
}
我可能会将标记化循环重写为for
循环,以在循环定义本身中包含nval
增量,例如
for (; token; token = strtok (NULL, ", "), nval++) {
sum += strtod (token, NULL);
printf (" %8s, sum : %9.2lf\n", token, sum);
}
在任何一种情况下,每个字符串的sum
和average
将如下所示:
$ ./bin/strtok_arr1
12, sum : 12.00
34, sum : 46.00
56, sum : 102.00
78, sum : 180.00
----------------------------
average : 45.00
82.16, sum : 82.16
41.296, sum : 123.46
----------------------------
average : 61.73
2, sum : 2.00
-3, sum : -1.00
5, sum : 4.00
-7, sum : -3.00
11, sum : 8.00
-13, sum : -5.00
17, sum : 12.00
-19, sum : -7.00
----------------------------
average : -0.88
9.00009, sum : 9.00
90.0009, sum : 99.00
900.009, sum : 999.01
9000.09, sum : 9999.10
90000.9, sum : 100000.00
----------------------------
average : 20000.00
仔细看看,如果您有任何其他问题,请告诉我。
答案 1 :(得分:1)
r
获取一个指向字符数组的指针(我在这里称之为“字符串”),但是你传递的是字符串数组。
此外,bool buttonLocked;
System.Timers.Timer t = new System.Timers.Timer(1000); //however many milliseconds
t.Elapsed += new EventHandler(resetFlag);
private void button_clicked(object sender, EventArgs e){
if(!buttonLocked){
// Handle Click
buttonLocked= true;
t.Enabled = true;
}
}
private void resetFlag(){
buttonLocked = false;
t.Enabled = false;
}
通过使用空字符替换分隔符来修改您传入的字符串。
传递给strtok()
的字符串数组包含指向数组中各个字符串的指针。因此,乱码显示是这些指针显示为字符串的结果。此外,当strtok()
修改您提供的“字符串”时,这可能会导致各种内存损坏。
答案 2 :(得分:1)
试图预测BLUEPIXY与Nuchy的解决方案存在的两个问题,下面的代码将常量字符串复制到用户分配的内存中,以便在Unix上修改它们没有BUS错误。
以下使用较新的,可重入的strsep()
代替strtok()
。
", "
,如果传递给strsep()
,与原始代码不同,不会破坏和删除逗号和空格的组合,它会在两者处中断。但只是使用","
会在数据上留下不需要的空间,我会单独删除。
最后,我重新格式化了数据以清楚地表明有四个输入字符串,而不是三个,并计算字符串数而不是硬编码计数:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE (1024)
int main(int argc, char *argv[]) {
char strings[][BUFFER_SIZE] = {
"12, 34, 56, 78",
"82.16, 41.296",
"2, -3, 5, -7, 11, -13, 17, -19",
"9.00009, 90.0009, 900.009, 9000.09, 90000.9"
};
size_t limit = sizeof(strings) / BUFFER_SIZE;
for (size_t i = 0; i < limit; i++) {
char *token, *string = strings[i];
while ((token = strsep(&string, ",")) != NULL) {
while (isspace(*token)) {
token++;
}
printf("%s\n", token);
}
}
return 0;
}
答案 3 :(得分:0)
您需要单独标记每个字符串 - strtok()函数接受指向char的指针作为其第一个参数:
char *strtok(char * str, const char * delim);
类似的东西:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
char* s[] = { "12, 34, 56, 78", "82.16, 41.296",
"2, -3, 5, -7, 11, -13, 17, -19",
"9.00009, 90.0009, 900.009, 9000.09, 90000.9" };
int sNo = 0;
while (sNo < 4) {
char *token = strtok(s[sNo++], ", ");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ", ");
}
}
return 0;
}
这当然要求您提前知道数组的大小。