运行C程序时出现运行时错误, 这是C源代码(parsing.h头代码稍低):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parsing.h"
int main()
{
printf("Enter text seperated by single spaces :\n");
char *a = malloc(sizeof(char)*10);
gets(a);
char **aa = Split(a, ' ');
int k = SplitLen(a, ' ');
int i = 0;
for(;i<k;i++)
{
printf("%s\n", aa[i]);
}
free(a);
free(aa);
return 0;
}
和parsing.h文件:
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
char** Split(char* a_str, const char a_delim)
{
char** result = 0;
int count = 0;
char* tmp = a_str;
char* last_comma = 0;
/* Count how many elements will be extracted. */
while (*tmp)
{
if (a_delim == *tmp)
{
count++;
last_comma = tmp;
}
tmp++;
}
/* Add space for trailing token. */
count += last_comma < (a_str + strlen(a_str) - 1);
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
result = malloc(sizeof(char*) * count);
if (result)
{
size_t idx = 0;
char* token = strtok(a_str, ",");
while (token)
{
assert(idx < count);
*(result + idx++) = strdup(token);
token = strtok(0, ",");
}
assert(idx == count - 1);
*(result + idx) = 0;
}
return result;
}
int SplitLen(char *src, char sep)
{
int result = 0;
int i;
for(i = 0; i<strlen(src); i++)
{
if(src[i] == sep)
{
result += 1;
}
}
return result;
}
我确信大部分代码都是不需要的,但我发布了全部内容,以防有一些相关性,这是运行时错误:
a.out: parsing.h:69: Split: Assertion `idx == count - 1' failed.
Aborted
在此先感谢并获取信息我没有对整个程序进行编程,但从某些地方拍摄了一些内容,但大多数是我的编程谢谢!。
答案 0 :(得分:1)
assert函数的目的是,如果作为参数传递的条件为false,则会停止程序。这告诉你的是,当你在第69行运行你的程序idx != count - 1
时。我没有花时间检查你的程序执行有什么导入,但显然(?){{1}那意味着等于idx
。
这有帮助吗?
答案 1 :(得分:0)
有很多问题。我忽略了分成两个文件的代码;我将其视为单个文件(请参阅提问题)。
请勿使用gets()
。切勿使用gets()
。不要使用gets()
。我说了三次;一定是真的。请注意,gets()
不再是标准C函数(它已从C11标准 - ISO / IEC 9899:2011中删除),因为它无法安全使用。请改用fgets()
或其他安全功能。
您不需要为10个字符的字符串使用动态内存分配;使用局部变量(更简单)。
你需要一个更大的字符串 - 想想4096。
您不检查是否有任何数据;总是检查输入函数调用。
你没有释放main()
末尾的所有子串,从而泄漏内存。
一个主要问题 Split()
代码切片并切断输入字符串,以便SplitLen()
无法为您提供Split()
所做的相同答案字段数。 strtok()
函数具有破坏性。它还将多个相邻分隔符视为单个分隔符。您的代码不会考虑差异。
另一个主要问题是您根据传递到Split()
函数的分隔符分析字符串,但您使用strtok(..., ',')
实际分割逗号。这与评论和名称更加一致,但完全误导你。这就是你的断言被解雇的原因。
除非您使用其提供的额外设施,否则无需包含<malloc.h>
。你不是,所以你不应该包括它; <stdlib.h>
完全声明malloc()
和free()
。
此代码适合我;我已经注释了我改变的大部分地方。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int altSplitLen(char **array);
static char **Split(char *a_str, const char a_delim);
static int SplitLen(char *src, char sep);
int main(void)
{
printf("Enter text separated by single spaces:\n");
char a[4096]; // Simpler
if (fgets(a, sizeof(a), stdin) != 0) // Error checked!
{
char **aa = Split(a, ' ');
int k = SplitLen(a, ' ');
printf("SplitLen() says %d; altSplitLen() says %d\n", k, altSplitLen(aa));
for (int i = 0; i < k; i++)
{
printf("%s\n", aa[i]);
}
/* Workaround for broken SplitLen() */
{
puts("Loop to null pointer:");
char **data = aa;
while (*data != 0)
printf("[%s]\n", *data++);
}
{
// Fix for major leak!
char **data = aa;
while (*data != 0)
free(*data++);
}
free(aa); // Major leak!
}
return 0;
}
char **Split(char *a_str, const char a_delim)
{
char **result = 0;
size_t count = 0;
char *tmp = a_str;
char *last_comma = 0;
/* Count how many elements will be extracted. */
while (*tmp)
{
if (a_delim == *tmp)
{
count++;
last_comma = tmp;
}
tmp++;
}
/* Add space for trailing token. */
count += last_comma < (a_str + strlen(a_str) - 1);
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
result = malloc(sizeof(char *) * count);
if (result)
{
char delim[2] = { a_delim, '\0' }; // Fix for inconsistent splitting
size_t idx = 0;
char *token = strtok(a_str, delim);
while (token)
{
assert(idx < count);
*(result + idx++) = strdup(token);
token = strtok(0, delim);
}
assert(idx == count - 1);
*(result + idx) = 0;
}
return result;
}
int SplitLen(char *src, char sep)
{
int result = 0;
for (size_t i = 0; i < strlen(src); i++)
{
if (src[i] == sep)
{
result += 1;
}
}
return result;
}
static int altSplitLen(char **array)
{
int i = 0;
while (*array++ != 0)
i++;
return i;
}
示例运行:
$ parsing
Enter text separated by single spaces:
a b c d e f gg hhh iii jjjj exculpatory evidence
SplitLen() says 0; altSplitLen() says 12
Loop to null pointer:
[a]
[b]
[c]
[d]
[e]
[f]
[gg]
[hhh]
[iii]
[jjjj]
[exculpatory]
[evidence
]
$
请注意fgets()
保留换行符,gets()
不换行,因此换行符中包含换行符。还要注意打印数据的printf()
如何显示字符串的限制;这在很多场合都非常有用。