将空白拆分为字符串,并将其存储在C中的表中,不带库
上周我在课堂上布置了一个作业,我必须用空格、制表符等分隔符拆分一个字符串,并将每个“单词”存储在一个数组中。我想我很接近,但我的输出非常奇怪,所以如果有人能告诉我忘记了什么,那就太好了。唯一的问题是我只能使用将空白拆分为字符串,并将其存储在C中的表中,不带库,c,string,malloc,C,String,Malloc,上周我在课堂上布置了一个作业,我必须用空格、制表符等分隔符拆分一个字符串,并将每个“单词”存储在一个数组中。我想我很接近,但我的输出非常奇怪,所以如果有人能告诉我忘记了什么,那就太好了。唯一的问题是我只能使用malloc char **ft_split_whitespaces(char *str) { int i; int j; int k; char **tab; i = 0; j = 0; k =
malloc
char **ft_split_whitespaces(char *str)
{
int i;
int j;
int k;
char **tab;
i = 0;
j = 0;
k = 0;
tab = (char**)malloc(sizeof(*tab) * (ft_nb_words(str) + 1));
while (str[i])
{
while (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
i++;
if (str[i])
{
if ((tab[j] = (char*)malloc(sizeof(char) * (ft_len_word(str + i) + 1))) == NULL)
return (NULL);
while (k < ft_len_word(str + i))
tab[j][k++] = str[i++];
tab[j++][k] = '\0';
k = 0;
}
}
tab[j] = NULL;
return (tab);
}
char**ft\u分割\u空格(char*str)
{
int i;
int j;
int k;
字符**选项卡;
i=0;
j=0;
k=0;
tab=(char**)malloc(sizeof(*tab)*(ft_nb_单词(str)+1);
while(str[i])
{
而(str[i]=''| | str[i]='\t'| | str[i]='\n')
i++;
if(str[i])
{
if((tab[j]=(char*)malloc(sizeof(char)*(ft_len_word(str+i)+1))==NULL)
返回(空);
while(k
返回字长和字数的函数工作正常,因此我认为问题来自于主函数。如果将一个指针指向最后出现的特定字符(''\n'\t),则可以轻松处理此问题
char**ft\u分割\u空格(char*str)
{
int i;
int j;
int k;
字符**选项卡;
char*prevToken=str;
i=0;
j=0;
k=0;
tab=(char**)malloc(sizeof(*tab)*(ft_nb_单词(str)+1);
while(str[i]!='\0')
{
如果(str[i]=''| | str[i]='\t'| | str[i]='\n')
{
i++;
如果((制表符[j]=(字符*)malloc(字符大小)*(字符长度)+1))==NULL)
返回(空);
while(k
以下代码包含一些有用的C函数的实现
您搜索的函数是strtok()
。代码中还实现了函数strspn()
和strpbrk()
,因为strtok()
使用它们
解决这类问题的最好方法是研究C标准函数的实现
代码存储max 100标记(提取的字)的副本
您必须记住,函数strtok()
修改源字符串的内容,插入“\0”以终止找到的字符串
此处实现的功能包括:
- mystrtok()
- mystrspn()
- mystrpbrk()
#include <stdio.h>
#include <string.h> /* for the use of strcpy fn */
#include <malloc.h>
char * mystrtok (char * s, char * delim);
size_t mystrspn (const char *s, const char *accept);
char * mystrpbrk (const char *s, const char *accept);
char * mystrpbrk (const char *s, const char *accept)
{
while (*s != '\0')
{
const char *a = accept;
while (*a != '\0')
if (*a++ == *s)
return (char *) s;
++s;
}
return NULL;
}
size_t mystrspn (const char *s, const char *accept)
{
const char *p;
const char *a;
size_t count = 0;
for (p = s; *p != '\0'; ++p)
{
for (a = accept; *a != '\0'; ++a)
if (*p == *a)
break;
if (*a == '\0')
return count;
else
++count;
}
return count;
}
char * mystrtok (char *s, char *delim)
{
char *token;
static char *olds;
if (s == NULL) {
s = olds;
}
/* Scan leading delimiters. */
s += mystrspn (s, delim);
if (*s == '\0')
{
olds = s;
return NULL;
}
/* Find the end of the token. */
token = s;
s = mystrpbrk (token, delim);
if (s == NULL)
{
/* This token finishes the string. */
while(*olds)
olds++;
}
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}
int main(void)
{
char str[] = "I have an orange\tYou have some bananas\nShe has three pineapples\n";
char * x = NULL;
int cnt=0,i;
char **store;
/* Stores a max of 100 strings */
store = malloc(sizeof(char *)*100);
/* The total space for the tokens is
max the entire string + '\0' */
store[0] = malloc(strlen(str)+1);
/* Extract the first token */
x=mystrtok(str," \n");
while(x) {
printf("Storing %s\n",x);
/* Store a copy of the token */
strcpy(store[cnt],x);
store[cnt+1]=store[cnt]+strlen(x)+1;
cnt++;
/* extract the next token */
x=mystrtok(NULL," \n\t");
}
for(i=0;i<cnt;i++)
printf("Stored %s\n",store[i]);
free(store[0]);
free(store);
return 0;
}
#包括
#包括/*用于strcpy fn的使用*/
#包括
char*mystrtok(char*s,char*delim);
大小\u t mystrspn(常量字符*s,常量字符*accept);
char*mystrpbrk(const char*s,const char*accept);
char*mystrpbrk(常量char*s,常量char*accept)
{
而(*s!='\0')
{
const char*a=接受;
而(*a!='\0')
如果(*a++==*s)
返回(字符*)s;
++s;
}
返回NULL;
}
大小\u t mystrspn(常量字符*s,常量字符*accept)
{
常量字符*p;
常量字符*a;
大小\u t计数=0;
对于(p=s;*p!='\0';++p)
{
对于(a=接受;*a!='\0';++a)
如果(*p==*a)
打破
如果(*a=='\0')
返回计数;
其他的
++计数;
}
返回计数;
}
char*mystrtok(char*s,char*delim)
{
字符*令牌;
静态字符;
如果(s==NULL){
s=老年人;
}
/*扫描前导分隔符*/
s+=mystrspn(s,delim);
如果(*s=='\0')
{
olds=s;
返回NULL;
}
/*查找标记的结尾*/
令牌=s;
s=mystrpbrk(令牌,delim);
如果(s==NULL)
{
/*此标记结束字符串*/
while(*olds)
olds++;
}
其他的
{
/*终止令牌并使其通过*/
*s='\0';
olds=s+1;
}
返回令牌;
}
内部主(空)
{
char str[]=“我有一个桔子\t你有一些香蕉\n她有三个菠萝\n”;
char*x=NULL;
int cnt=0,i;
字符**存储;
/*最多存储100个字符串*/
store=malloc(sizeof(char*)*100);
/*令牌的总空间为
最大值为整个字符串+'\0'*/
存储[0]=malloc(strlen(str)+1);
/*提取第一个令牌*/
x=mystrtok(str,“\n”);
while(x){
printf(“存储%s\n”,x);
/*存储令牌的副本*/
strcpy(存储[cnt],x);
存储[cnt+1]=存储[cnt]+strlen(x)+1;
cnt++;
/*提取下一个令牌*/
x=mystrtok(空,“\n\t”);
}
对于(i=0;i您的代码在调用ft\u len\u word
太多次时效率低下,但它似乎没有与malloc
故障上未定义的行为分开
问题可能存在于您的ft\u len\u word
或ft\u nb\u words
版本中。您应该发布一个完整的程序来展示问题,以便进行适当的调查
以下是不使用这些功能的修改版本:
#include <stdlib.h>
int ft_is_space(char c) {
return (c == ' ' || c == '\t' || c == '\n');
}
char **ft_split_whitespaces(const char *str) {
int i, j, k, len, in_space, nb_words;
char **tab;
nb_words = 0;
in_space = 1;
for (i = 0; str[i]; i++) {
if (ft_is_space(str[i]) {
in_space = 1;
} else {
nb_words += in_space;
in_space = 0;
}
}
tab = malloc(sizeof(*tab) * (nb_words + 1));
if (tab != NULL) {
i = 0;
j = 0;
while (str[i]) {
while (ft_is_space(str[i]))
i++;
if (str[i]) {
for (len = 1; str[i + len] && !ft_is_space(str[i + len]); len++)
continue;
if ((tab[j] = malloc(sizeof(*tab[j]) * (len + 1))) == NULL) {
while (j > 0)
free(tab[--j]);
free(tab);
return NULL;
}
for (k = 0; k < len; k++)
tab[j][k] = str[i + k];
tab[j++][len] = '\0';
i += len;
}
}
tab[j] = NULL;
}
return tab;
}
#包括
int ft_是_空间(字符c){
返回值(c=''| | c='\t'| | c='
#include <stdlib.h>
int ft_is_space(char c) {
return (c == ' ' || c == '\t' || c == '\n');
}
char **ft_split_whitespaces(const char *str) {
int i, j, k, len, in_space, nb_words;
char **tab;
nb_words = 0;
in_space = 1;
for (i = 0; str[i]; i++) {
if (ft_is_space(str[i]) {
in_space = 1;
} else {
nb_words += in_space;
in_space = 0;
}
}
tab = malloc(sizeof(*tab) * (nb_words + 1));
if (tab != NULL) {
i = 0;
j = 0;
while (str[i]) {
while (ft_is_space(str[i]))
i++;
if (str[i]) {
for (len = 1; str[i + len] && !ft_is_space(str[i + len]); len++)
continue;
if ((tab[j] = malloc(sizeof(*tab[j]) * (len + 1))) == NULL) {
while (j > 0)
free(tab[--j]);
free(tab);
return NULL;
}
for (k = 0; k < len; k++)
tab[j][k] = str[i + k];
tab[j++][len] = '\0';
i += len;
}
}
tab[j] = NULL;
}
return tab;
}
Example Usage
char str[] = "A,B,,,C";
printf("1 %s\n",zstring_strtok(s,","));
printf("2 %s\n",zstring_strtok(NULL,","));
printf("3 %s\n",zstring_strtok(NULL,","));
printf("4 %s\n",zstring_strtok(NULL,","));
printf("5 %s\n",zstring_strtok(NULL,","));
printf("6 %s\n",zstring_strtok(NULL,","));
Example Output
1 A
2 B
3 ,
4 ,
5 C
6 (null)
char *zstring_strtok(char *str, const char *delim) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=0; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
while(str[strlength])
strlength++;
/* find the first occurrence of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignment requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}