繁体   English   中英

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

[英]How to analyze strings from a dynamically allocated char array in C

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括起来#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, sizeof(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",
                file,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,sizeof(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,sizeof(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,"r");
    if (fin == NULL) {
        printf("unable to open list of dictionary words '%s' -- %s\n",
            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,"r");
        if (fin == NULL) {
            printf("unable to open list of words to check '%s' -- %s\n",
                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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM