微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从C中动态分配的char数组分析字符串

如何解决如何从C中动态分配的char数组分析字符串

char *arrList;
arrList = (char*) malloc(sizeof(char) * 4);
arrList = input;
printf("%s\n",arrList);  //The words I am attempting to analyze
    
int numWords = 0;

for(int i = 0; i < *arrList; i++){
    if(arrList[i] == ' '){
        numWords++;
    }
}

char *ptr = strtok(arrList,delim);
printf("\n%s",ptr);

int j = 0 ;
while(j <= numWords){
   checkWord(*ptr);  //This is where I am having issues
    
   ptr = strtok(NULL,delim);
   printf("\n%s",ptr);
   j++;
}

因此,我尝试输入“ qwp plm vzxyui coqwerty”之类的输入并将其放入动态分配的数组中。此外,我想能够将某些单词与其他单词分开,然后对所述单词进行解码。我遇到的问题是能够采用这些句段或单词并逐个“看”它们以进行测试。

void checkWord(char ptr){ // be able to test to see if word is valid
    char *word;
    word = (char*) malloc(sizeof(char) * 4);
    *word = ptr;
    
    printf("\n Word is : %s",word);
}

这是我尝试使用的每个单词的功能。当我运行该程序时,我似乎在某处丢失了内存,信息也不会通过。

任何建议将不胜感激!我只是想学习:)

下面是while循环之前的其他代码

 char input[300];

/* set up an infinite loop */
while(1){
    /* get line of input from standard input */
    printf ("\nEnter input to check or q to quit\n");
    fgets(input,300,stdin);

    /* remove the newline character from the input */
    int i = 0;
    while (input[i] != '\n' && input[i] != '\0'){
        i++;
}
input[i] = '\0';

解决方法

代码有很多问题。由于没有完整代码,因此情况更加复杂。

通常,何时使用charchar *char **。代码无法干净地编译。

搜索列表时,我们只想扫描现有列表(即我们不需要分配新内容)。

由于所有这些,这些错误太多了,无法在这里提及。

但是,我整理了一个版本,其中显示了原始代码和[我的]重构代码,并带有错误的注释。

然后,第二个版本已清理并正常工作


这是带注释的版本。它是不完整的,不会编译,只是试图显示一些错误。请注意,我必须获得可观的“诗意许可”才能对代码进行重新排序和重新组合。新旧代码用#if BUG#if ! BUG

括起来
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

// NOTE/BUG: this a pointer to a _single_ string and _not_ a pointer to a _list_
// of strings -- and,we need to keep track of the count in the list
#if BUG
char *arrList;
#else
size_t arrCount;
char **arrlist;
#endif

// be able to test to see if word is valid
// NOTE/BUG: "char ptr" is a single character and _not_ a pointer to an array
// of characters (i.e. a C string)
#if BUG
void
checkWord(char ptr)
#else
int
checkWord(const char *ptr)
#endif
{
    char *word;

#if ! BUG
    int arridx;
    char **arrcur;
    int match = 0;
#endif

// NOTE/BUG: no need to malloc anything new when _checking_ for a list
#if BUG
    word = (char *) malloc(sizeof(char) * 4);
    *word = ptr;
    printf("\n Word is : %s",word);
#else
    for (int arridx = 0; arridx < arrCount; ++arridx) {
        word = arrList[arridx];
        if (strcmp(str,word) == 0) {
            match = 1;
            break;
        }
    }
    printf("The word '%s' %s a valid word\n",match ? "is" : "is not");

    return match;
#endif
}

#if ! BUG
void
addword(const char *str)
{
    size_t arridx;

    arridx = arrCount++;

    arrList = realloc(arrList,sizeof(*arrlist) * (arrCount + 1));

    if (arrList == NULL) {
        printf("addword: unable to realloc -- %s\n",strerror(errno));
        exit(1);
    }

    arrList[arridx] = strdup(str);
    arrList[arridx] = NULL;
}

void
loadwords(FILE *fin)
{
    char *cp;
    char *inp;
    char input[300];

    while (1) {
        cp = fgets(input,sizeof(input),fin);
        if (cp == NULL)
            break;

        inp = input;
        while (1) {
            cp = strtok(inp," \t\n");
            inp = NULL;

            if (cp == NULL)
                break;

            addword(cp);
        }
    }
}
#endif

#if BUG
void
checkallold(const char *file)
{

    arrList = (char *) malloc(sizeof(char) * 4);
    arrList = input;
    //The words I am attempting to analyze
    printf("%s\n",arrList);

    for (int i = 0; i < *arrList; i++) {
        if (arrList[i] == ' ') {
            numWords++;
        }
    }

    char *ptr = strtok(arrList,delim);
    printf("\n%s",ptr);

    int j = 0;
    int numWords = 0;
    while (j <= numWords) {
        // This is where I am having issues
        checkWord(*ptr);

        ptr = strtok(NULL,delim);
        printf("\n%s",ptr);
        j++;
    }
}
#endif

#if ! BUG
void
checkallfix(FILE *fin)
#if BUG
    /* set up an infinite loop */
#else
    // read in all words to check
#endif
    while (1) {
        /* get line of input from standard input */
        printf("\nEnter input to check or q to quit\n");
#if BUG
        fgets(input,300,stdin);
#else
        if (fgets(input,fin) == NULL)
            break;
#endif

        /* remove the newline character from the input */
#if BUG
        int i = 0;
        while (input[i] != '\n' && input[i] != '\0') {
            i++;
        }
        input[i] = '\0';
#else
        cp = strchr(input,'\n');
        if (cp != NULL)
            *cp = 0;
        checkWord(input);
#endif
    }
}
#endif

int
main(int argc,char **argv)
{
#if BUG
    char input[300];
#else
    char *cp;
    char *file;
    FILE *fin;
#endif

#if ! BUG
    --argc;
    ++argv;

    // read in list of valid words
    if (argc <= 0) {
        printf("No dictionary file specified\n");
        exit(1);
    }
    --argc;
    file = *argv++;
    fin = fopen(file,"r");
    if (fin == NULL) {
        printf("unable to open list of dictionary words '%s' -- %s\n",file,strerror(errno));
        exit(1);
    }
    loadwords(fin);
    fclose(fin);
#endif

#if BUG
    checkallold();
#else
    // read in list of valid words
    if (argc <= 0) {
        fin = stdin;
        checkallfix(fin);
    }
    else {
        --argc;
        file = *argv++;
        fin = fopen(file,"r");
        if (fin == NULL) {
            printf("unable to open list of words to check '%s' -- %s\n",strerror(errno));
            exit(1);
        }
        checkallfix(fin);
        fclose(fin);
    }
#endif
}

这是清理,重构和工作的版本。我添加了更多评论以解释发生了什么。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

size_t arrcount;                        // number of elements in arrlist
char **arrlist;                         // dictionary list

// checkWord -- be able to test to see if word is valid
int
checkWord(const char *ptr)
{
    char *word;
    int arridx;
    int match = 0;

    for (arridx = 0;  arridx < arrcount;  ++arridx) {
        word = arrlist[arridx];
        if (strcmp(ptr,word) == 0) {
            match = 1;
            break;
        }
    }

    if (match)
        printf("The word '%s' is in the dictionary\n",ptr);
    else
        printf("'%s' is not a valid word\n",ptr);

    return match;
}

// addword -- add new dictionary word
void
addword(const char *str)
{
    size_t arridx;

    arridx = arrcount++;

    // extend the dictionary list (allowing an extra element for a NULL)
    arrlist = realloc(arrlist,sizeof(*arrlist) * (arrcount + 1));
    if (arrlist == NULL) {
        printf("addword: unable to realloc -- %s\n",strerror(errno));
        exit(1);
    }

    // we must dup the string because,otherwise,it will be lost on the
    // next input line when the 'input' buffer is reused
    arrlist[arridx] = strdup(str);

    // add null pointer at end (e.g. just like argv)
    arrlist[arrcount] = NULL;
}

// loadwords -- load up all dictionary words
void
loadwords(FILE *fin)
{
    char *cp;
    char *inp;
    char input[300];

    while (1) {
        // get a line
        cp = fgets(input,fin);
        if (cp == NULL)
            break;

        // parse all tokens/words in the line
        inp = input;
        while (1) {
            cp = strtok(inp," \t\n");
            inp = NULL;

            // stop if nothing more
            if (cp == NULL)
                break;

            // add single new word
            addword(cp);
        }
    }
}

// checkallfix -- check all words
void
checkallfix(FILE *fin)
{
    char *cp;
    char input[300];

    // read in all words to check
    while (1) {
        // prompt user
        if (fileno(fin) == 0)
            printf("\nEnter input to check or q to quit\n");

        // get input line
        cp = fgets(input,fin);
        if (cp == NULL)
            break;

        /* remove the newline character from the input */
        cp = strchr(input,'\n');
        if (cp != NULL)
            *cp = 0;

        // stop ...
        if (strcmp(input,"q") == 0)
            break;

        // is this word in the dictionary?
        checkWord(input);
    }
}

int
main(int argc,char **argv)
{
    char *file;
    FILE *fin;

    --argc;
    ++argv;

    // read in list of valid words
    if (argc <= 0) {
        printf("No dictionary file specified\n");
        exit(1);
    }
    --argc;
    file = *argv++;
    fin = fopen(file,strerror(errno));
        exit(1);
    }
    loadwords(fin);
    fclose(fin);

    // check words against dictionary
    if (argc <= 0) {
        fin = stdin;
        checkallfix(fin);
    }
    else {
        --argc;
        file = *argv++;
        fin = fopen(file,strerror(errno));
            exit(1);
        }
        checkallfix(fin);
        fclose(fin);
    }

    return 0;
}

这是一个示例词典文件:

qwp plm vzxyui coqwerty
able baker charlie delta
quick brown fox jumps over the lazy dog
sherlock holmes was a fine detective

以下是一个示例输入文件,可根据字典进行测试:

coqwerty
able
baker
charlie
delta
epsilon
fox
the
shylock
homes
bill and ted
bogus
journey

这是程序的输出:

The word 'coqwerty' is in the dictionary
The word 'able' is in the dictionary
The word 'baker' is in the dictionary
The word 'charlie' is in the dictionary
The word 'delta' is in the dictionary
'epsilon' is not a valid word
The word 'fox' is in the dictionary
The word 'the' is in the dictionary
'shylock' is not a valid word
'homes' is not a valid word
'bill and ted' is not a valid word
'bogus' is not a valid word
'journey' is not a valid word

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。