在 C 中,strtok() 适用于“,”(逗号)但不适用于空格“”。使用空格时出现段错误
In C strtok() is working for "," (commas) but not for spaces " ". Getting a seg fault when working with spaces
我是新来的。这是我的第一个post!
所以我用 C 编写了代码,以接收逗号分隔的文本文件并将其读入二维数组。我为此使用了 strtok() 。有效。下面是代码:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *data = fopen(argv[1], "r");
if (data == NULL)
{
printf("Could not open 11.txt\n");
return 1;
}
char table[20][20][3];
char buffer[60];
int i = 0;
while (fscanf(data, "%s", buffer) != EOF)
{
int j = 0;
for (char *s = strtok(buffer, ","); s != NULL; s = strtok(NULL, ","))
{
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
j++;
}
i++;
}
printf("%s\n", table[19][0]);
return 0;
}
我试图读入二维数组的数据如下所示:
08,02,22,97
49,49,99,40
81,49,31,73
52,70,95,23
它是一个 20x20 的矩阵,数字之间用逗号分隔。
上面的程序工作正常(我打印出这个二维数组的一个元素来检查程序是否工作)。但是当数字被 spaces 分隔时:
08 02 22 97
49 49 99 40
81 49 31 73
52 70 95 23
当我在 strtok() 函数中将“,”替换为“”时,出现段错误。我不知道为什么会这样。
感谢您的帮助!
编辑:
错误已修复!
来自莫斯科的@Vlad 非常正确地指出 fcanf() 不是用于将带有白色 space 的字符串读入缓冲区的正确函数。他建议改为使用 fgets(),它可以读取白色 space。我仍然面临段错误,因为 strtok() 返回的第一个标记是指向 NULL 的指针。我不确定为什么要这样做,因为当我在 while 循环中使用相同字符串的 strtok() 数组而不使用 fgets() 时,如图所示,没有问题:
char str[] = "08 02 22 97";
因此,为了解决这个问题,我在 for 循环中放置了一个条件,如果 strtok() 返回 NULL 指针,则跳至下一次迭代。
第二个问题是我的缓冲区不够大(spaces 是 4 个字节,而 char 是 1 个字节)。解决了这两个问题后,我的代码就可以工作了!
下面是更正后的代码:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *data = fopen(argv[1], "r");
if (data == NULL)
{
printf("Could not open 11.txt\n");
return 1;
}
char table[20][20][3];
char buffer[61];
int i = 0;
while (fgets(buffer, sizeof(buffer), data) != NULL)
{
int j = 0;
for (char *s = strtok(buffer, " "); s != NULL; s = strtok(NULL, " "))
{
if (s == NULL)
{
continue;
}
else
{
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
j++;
}
}
i++;
}
printf("%i\n", atoi(table[19][19]));
return 0;
}
带有格式说明符 %s
的函数 fscanf
读取数据,直到遇到白色 space 字符。所以你不能像在 while 语句
中那样使用函数 fscanf
while (fscanf(data, "%s", buffer) != EOF)
读取包含嵌入白色的字符串 spaces.
而是使用标准 C 函数 fgets
。
注意那个而不是这个for循环
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
您可以使用标准字符串函数 strcpy
作为例子
strcpy( table[i][j], s );
还有这个电话
printf("%s\n", table[20][0]);
调用未定义的行为,因为对于声明为
的数组
char table[20][20][3];
第一个索引的有效范围是 ]0, 20 )。那就是你不能使用值 20 作为索引。
我是新来的。这是我的第一个post! 所以我用 C 编写了代码,以接收逗号分隔的文本文件并将其读入二维数组。我为此使用了 strtok() 。有效。下面是代码:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *data = fopen(argv[1], "r");
if (data == NULL)
{
printf("Could not open 11.txt\n");
return 1;
}
char table[20][20][3];
char buffer[60];
int i = 0;
while (fscanf(data, "%s", buffer) != EOF)
{
int j = 0;
for (char *s = strtok(buffer, ","); s != NULL; s = strtok(NULL, ","))
{
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
j++;
}
i++;
}
printf("%s\n", table[19][0]);
return 0;
}
我试图读入二维数组的数据如下所示:
08,02,22,97
49,49,99,40
81,49,31,73
52,70,95,23
它是一个 20x20 的矩阵,数字之间用逗号分隔。 上面的程序工作正常(我打印出这个二维数组的一个元素来检查程序是否工作)。但是当数字被 spaces 分隔时:
08 02 22 97
49 49 99 40
81 49 31 73
52 70 95 23
当我在 strtok() 函数中将“,”替换为“”时,出现段错误。我不知道为什么会这样。 感谢您的帮助!
编辑: 错误已修复! 来自莫斯科的@Vlad 非常正确地指出 fcanf() 不是用于将带有白色 space 的字符串读入缓冲区的正确函数。他建议改为使用 fgets(),它可以读取白色 space。我仍然面临段错误,因为 strtok() 返回的第一个标记是指向 NULL 的指针。我不确定为什么要这样做,因为当我在 while 循环中使用相同字符串的 strtok() 数组而不使用 fgets() 时,如图所示,没有问题:
char str[] = "08 02 22 97";
因此,为了解决这个问题,我在 for 循环中放置了一个条件,如果 strtok() 返回 NULL 指针,则跳至下一次迭代。 第二个问题是我的缓冲区不够大(spaces 是 4 个字节,而 char 是 1 个字节)。解决了这两个问题后,我的代码就可以工作了!
下面是更正后的代码:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *data = fopen(argv[1], "r");
if (data == NULL)
{
printf("Could not open 11.txt\n");
return 1;
}
char table[20][20][3];
char buffer[61];
int i = 0;
while (fgets(buffer, sizeof(buffer), data) != NULL)
{
int j = 0;
for (char *s = strtok(buffer, " "); s != NULL; s = strtok(NULL, " "))
{
if (s == NULL)
{
continue;
}
else
{
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
j++;
}
}
i++;
}
printf("%i\n", atoi(table[19][19]));
return 0;
}
带有格式说明符 %s
的函数 fscanf
读取数据,直到遇到白色 space 字符。所以你不能像在 while 语句
fscanf
while (fscanf(data, "%s", buffer) != EOF)
读取包含嵌入白色的字符串 spaces.
而是使用标准 C 函数 fgets
。
注意那个而不是这个for循环
for (int k = 0; k < strlen(s) + 1; k++)
{
table[i][j][k] = s[k];
}
您可以使用标准字符串函数 strcpy
作为例子
strcpy( table[i][j], s );
还有这个电话
printf("%s\n", table[20][0]);
调用未定义的行为,因为对于声明为
的数组char table[20][20][3];
第一个索引的有效范围是 ]0, 20 )。那就是你不能使用值 20 作为索引。