Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在没有内置函数的情况下拆分数组_C_Loops_Tokenize_C Strings - Fatal编程技术网

C 在没有内置函数的情况下拆分数组

C 在没有内置函数的情况下拆分数组,c,loops,tokenize,c-strings,C,Loops,Tokenize,C Strings,下面的代码旨在获取输入字符串,如我的名字是Smith和outputs My name is Smith 而且还必须排除以下内容:。空间,只有这三个,但它输出,我不允许使用任何像strlen或strtok这样的东西 我在代码中的任何地方都搜索到了错误,但我似乎无法找到它 int main() { int wordSize = 0; char str[81]; char* ptr_to_word[81]; gets_s(str); for (cha

下面的代码旨在获取输入字符串,如我的名字是Smith和outputs

My 
name 
is 
Smith
而且还必须排除以下内容:。空间,只有这三个,但它输出,我不允许使用任何像strlen或strtok这样的东西

我在代码中的任何地方都搜索到了错误,但我似乎无法找到它

int main()
{
    int wordSize = 0;
    char str[81];
    char* ptr_to_word[81];

    gets_s(str);

    for (char* res_p = &(str[0]); *res_p != '\0'; res_p++) {
        if ((*res_p != '.') || (*res_p != ',') || (*res_p != ' '))
        {
            ptr_to_word[wordSize] = res_p;
            wordSize++;
        }
    }

    if (wordSize == 0)
    {
        printf("no solution");
    }

    else
    {
        for (int i = 0; i < wordSize; i)
        {
            char* a = ptr_to_word[i];
            while ((*a != '.') && (*a != ',') && (*a != ' ') && (*a != '\0'))
            {
                printf("%c", *a);
                a++;
            }
            printf("\n");
        }
    }
    return 0;
}

在该循环中if语句的条件下

for (char* res_p = &(str[0]); *res_p != '\0'; res_p++) {
    if ((*res_p != '.') || (*res_p != ',') || (*res_p != ' '))
    {
        ptr_to_word[wordSize] = res_p;
        wordSize++;
    }
}
您必须使用逻辑AND运算符,而不是类似逻辑OR运算符的运算符

    if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' '))
尽管如此,循环在任何情况下都是错误的,因为变量wordSize不统计单词,而是统计不等于if语句中列出的字符的每个字符

要输出单独的单词,不需要声明指向单词开头的指针数组。一旦找到每个单词的开头,就可以输出它

这是一个非常简单的演示程序

#include <stdio.h>

int main(void) 
{
    enum { N = 81 };
    char s[N];

    fgets( s, N, stdin );

    for ( const char *p = s; *p; )
    {
        int wordSize = 0;
        while ( *p && *p != '.' && *p != ',' && *p != ' ' && *p != '\t' && *p != '\n' )
        {
            ++wordSize;
            ++p;
        }

        if ( wordSize )
        {
            printf( "%.*s\n", wordSize, p - wordSize );
        }
        else
        {
            ++p;
        }
    }

    return 0;
}

我在分隔符列表中附加了制表符“\t”和新行符“\n”,可以通过函数fgets插入到输入字符串中。

在此循环中的if语句条件下

for (char* res_p = &(str[0]); *res_p != '\0'; res_p++) {
    if ((*res_p != '.') || (*res_p != ',') || (*res_p != ' '))
    {
        ptr_to_word[wordSize] = res_p;
        wordSize++;
    }
}
您必须使用逻辑AND运算符,而不是类似逻辑OR运算符的运算符

    if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' '))
尽管如此,循环在任何情况下都是错误的,因为变量wordSize不统计单词,而是统计不等于if语句中列出的字符的每个字符

要输出单独的单词,不需要声明指向单词开头的指针数组。一旦找到每个单词的开头,就可以输出它

这是一个非常简单的演示程序

#include <stdio.h>

int main(void) 
{
    enum { N = 81 };
    char s[N];

    fgets( s, N, stdin );

    for ( const char *p = s; *p; )
    {
        int wordSize = 0;
        while ( *p && *p != '.' && *p != ',' && *p != ' ' && *p != '\t' && *p != '\n' )
        {
            ++wordSize;
            ++p;
        }

        if ( wordSize )
        {
            printf( "%.*s\n", wordSize, p - wordSize );
        }
        else
        {
            ++p;
        }
    }

    return 0;
}

我在分隔符列表中添加了制表符“\t”和新行符“\n”,可以通过函数fgets插入到输入字符串中。

首先,此条件

如果*res_p!='。|124;*res_p!=','|*回复

永远都是真的,想想看,*res_p永远不是'。'或者不是','。但是,如果将运算符更改为&&您的代码仍将生成相同的结果

带有| |运算符的第一个循环将指向输入字符串中每个字符的指针写入数组ptr|u to|u字,并且仅由于第二个循环中的某个条件,才会打印“s”和“.”

如果将运算符更改为&&如是

if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' ')
您将把除“.”、“”和“”之外的所有指针写入数组,例如ptr_to_单词[0]将指向“My name is Smith”,ptr_to_单词[1]指向“y name is Smith”,等等

我已经对您的代码做了一些更改,以便它能够按预期工作

void split_str(char *str)
{
    int wordSize = 0;
    char *ptr_to_word[81];
    char *res_p = &(str[0]);
    int i = 0;

    for (; *res_p != '\0'; res_p++) {

        if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' '))
        {
            wordSize++;
        }
        else
        {
            ptr_to_word[i] = res_p - wordSize;
            wordSize = 0;
            i++;
        }
    }

    ptr_to_word[i] = res_p - wordSize;
    ptr_to_word[i + 1] = NULL;

    if (i == 0)
    {
        printf("no solution\n");
    }
    else
    {
        for (int i = 0; ptr_to_word[i]; i++)
        {
            char* a = ptr_to_word[i];
            while ((*a != '.') && (*a != ',') && (*a != ' ') && (*a != '\0'))
            {
                printf("%c", *a);
                a++;
            }
            printf("\n");
        }
    }
}
int main() {
    split_str("My name is Smith\n");
}
这样,只有在遇到点、逗号或空格时,才能将新值写入指针数组。对于所有其他字符,只需执行wordSize++即可跟踪单词的长度。我使用指针算法返回单词ptr_to_word[I]=res_p-wordSize;的开头

我试着对你的代码只做了很小的修改,只做了足够的工作。仍有一些事情需要更改以使其更好,例如,遇到“\0”时第一个循环结束。最后一个单词很可能以“\0”结尾,而不是“.”或“”。因此,它不会写入ptr_to_单词,我必须在循环后手动写入它。此外,您甚至不需要两个循环,您可以使用同一个指针。找到单词后立即输出的算术运算。所以我建议你这样做。自我代码审查,并进一步优化它


祝你好运

首先,这个条件

如果*res_p!='。|124;*res_p!=','|*回复

永远都是真的,想想看,*res_p永远不是'。'或者不是','。但是,如果将运算符更改为&&您的代码仍将生成相同的结果

带有| |运算符的第一个循环将指向输入字符串中每个字符的指针写入数组ptr|u to|u字,并且仅由于第二个循环中的某个条件,才会打印“s”和“.”

如果将运算符更改为&&如是

if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' ')
您将把除“.”、“”和“”之外的所有指针写入数组,例如ptr_to_单词[0]将指向“My name is Smith”,ptr_to_单词[1]指向“y name is Smith”,等等

我已经对您的代码做了一些更改,以便它能够按预期工作

void split_str(char *str)
{
    int wordSize = 0;
    char *ptr_to_word[81];
    char *res_p = &(str[0]);
    int i = 0;

    for (; *res_p != '\0'; res_p++) {

        if ((*res_p != '.') && (*res_p != ',') && (*res_p != ' '))
        {
            wordSize++;
        }
        else
        {
            ptr_to_word[i] = res_p - wordSize;
            wordSize = 0;
            i++;
        }
    }

    ptr_to_word[i] = res_p - wordSize;
    ptr_to_word[i + 1] = NULL;

    if (i == 0)
    {
        printf("no solution\n");
    }
    else
    {
        for (int i = 0; ptr_to_word[i]; i++)
        {
            char* a = ptr_to_word[i];
            while ((*a != '.') && (*a != ',') && (*a != ' ') && (*a != '\0'))
            {
                printf("%c", *a);
                a++;
            }
            printf("\n");
        }
    }
}
int main() {
    split_str("My name is Smith\n");
}
这样,只有在遇到点、逗号或空格时,才能将新值写入指针数组。对于所有其他字符,只需执行wordSize++即可跟踪单词的长度。我使用指针算法返回单词ptr_to_word[I]=res_p-wordSize;的开头

我试着对你的代码只做了很小的修改,只做了足够的工作。仍有一些事情需要更改以使其更好,例如,遇到“\0”时第一个循环结束。最后一个单词很可能以“\0”结尾,而不是“.”或“”。因此,它不会写入ptr_to_单词,我必须在循环后手动写入它。此外,您甚至不需要两个循环,您可以使用同一个指针。算术 ic在找到单词后立即输出该单词。所以我建议你这样做。自我代码审查,并进一步优化它


祝你好运

您的测试就像一个x | | a!=y | |。。。要明白这些测试永远都是正确的。假设a等于x。那么它不等于y。将| |改为&。你希望a不等于所有的,而不仅仅是一个。@TomKarzes有趣的是,它在底部的while循环中正确地完成了。@Barmar是的,我注意到了。第一个可能是尝试反转测试失败。问题是,您正在为每个非标点符号的字符添加指向ptr_to_单词的指针,而不仅仅是标点符号后的第一个字符。@DanielWalker我会,除了我没有仔细查看它,以确定这是否是唯一的问题。您的测试非常复杂!=x | | a!=y | |。。。要明白这些测试永远都是正确的。假设a等于x。那么它不等于y。将| |改为&。你希望a不等于所有的,而不仅仅是一个。@TomKarzes有趣的是,它在底部的while循环中正确地完成了。@Barmar是的,我注意到了。第一个可能是尝试反转测试失败。问题是,您正在为每个非标点符号的字符添加指向ptr_to_单词的指针,而不仅仅是标点符号后的第一个字符。@DanielWalker我会的,但我没有仔细查看它,以确定这是否是唯一的问题。这很有效,每次在句子的中间有一个定界符,在打印下一个单词之前,它会给一个很大的空间,我试图修复它,但是它只会产生更多的错误。这是有效的,每次在句子中间有一个定界符,在打印下一个单词之前,它会给一个大的空间,我试图修复它,但它只会产生更多的错误。