分配错误分配

我目前正在学习C,而我来自java。 我们的任务要求我们从可以添加的文件中计算字符串,或者要求用户输入字符串。 我们刚开始使用指针,并且查找了段错误发生的不同原因,但我不知道如何检查它是哪个问题。 我将所有的指针初始化为NULL,但它仍然不起作用,从我读到的这是发生分段错误的最常见原因。

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

int debug = 0;

int
main(int argc, char **argv)
{
    extern char *optarg;
    extern int optind;
    FILE* infile = NULL;
    int c, err = 0; 
    int lflag = 0, sflag = 0, count = 0; //flags and count
    char *shortWord = NULL, *longWord = NULL; //variable for shortest and longest word
    int shortest = 100, longest = 0; //longest char 100, shortest 0
    char *string = NULL;
    char *pch = NULL;
    static char usage[] = "usage: %s [-l] [-s] [filename]n";

    while ((c = getopt(argc, argv, "ls")) != -1)
        switch (c) 
        {
            case 'l':
                lflag  = 1;
                break;
            case 's':
                sflag = 1;
                break; 
            case '?':
                err = 1;
                break;
        }

    if (err) 
    {
        fprintf(stderr, usage, argv[0]);
        exit(1);
    }
    //checks for file and then runs loop for word count
    infile = fopen("myfile.txt","r");
    if (infile != NULL)
    {
        fgets(string, 100, infile);
        pch = strtok (string, " ,.-");
        while(pch != NULL)
        {
            count++;
            if (strlen(pch) > longest)
                longWord = pch;
            if (strlen(pch) < shortest)
                shortWord = pch;
            pch = strtok (NULL, " ,.");
        }
    } 
    //else, asks for string
    else
    {
        printf("Enter your string: n");
        fgets(string, 100, stdin);
        int len = strlen(string);
        count = len;
        pch = strtok ( string, " ,.-");
        while(pch != NULL)
        {
            count++;
            if (strlen(pch) > longest)
                longWord = pch;
            if (strlen(pch) < shortest)
                shortWord = pch;
            pch = strtok (NULL, " ,.");
        }   
    }

    //following lines compute value based on arguments
    if(lflag == 1)
    {
        printf("Longest word is %s", longWord);
    }
    if(sflag ==  1)
    {
        printf("Shortest word is %s", shortWord);
    }

    printf("Word count = %.2dn", count);

    exit(0);
}

他们是你的代码中的一些问题:

  • 您将string初始化为NULL ,然后将其用作fgets()的输入缓冲区。 fgets()需要指向一个char数组的指针,这个指针可以在堆栈中声明,也可以用malloc(3)动态分配。 您可以设置输入缓冲区,如char string[100]
  • fgets()必须被检查,因为当无法读取一行时它将返回NULL
  • 您的strtok()分隔符不是由fgets()附加的n字符。 您可以删除此换行符,也可以将其包含在分隔符中。 如果您想将其包含在分隔符中,请确保您的分隔符是" ,.-n"
  • 你可以使用strtok()来创建函数来解析你的输入,因为这样可以让你的main()变得更短并且减少代码中的重复性。 示例函数原型可以是void longest_shortest_words(char line[], char **longest, char **shortest, size_t *word_count); ,通过指针将最长最短的单词与单词的数量一起传递回main() 。 您也可以将最长和最短的单词存储在二维数组或指针数组中。
  • 您还应该明确检查您的文件是否正确打开。 应该包括这样的东西:

     infile = fopen("myfile.txt", "r");
     if (infile == NULL) {
         fprintf(stderr, "Failed to open filen");
         exit(EXIT_FAILURE);
     }
    
  • 在检查opt时检查? 因为你的switch语句中的字符是不正确的。 代替:

    case '?':
        err = 1;
        break;
    

    使用default ,其中包含输入的其他无效选项。 以下是您可以如何使用它的方法:

    default:
        fprintf(stderr, "usage: %s [-l] [-s] [filename]n", argv[0]);
        exit(EXIT_FAILURE);
    
  • 最后检查sflaglflag是不够的。 你应该检查longWordshortWord是否不是NULL

  • 以下是一些演示这些要点的示例代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define LINESIZE 100
    
    void longest_shortest_words(char line[], char **longest, char **shortest, size_t *wordcount);
    void print_output(int lflag, int sflag, char *longword, char *shortword, size_t wordcount);
    void remove_newline(char line[]);
    
    int main(int argc, char * const argv[]) {
        FILE *infile;
        char line[LINESIZE] = {''};
        int opt, sflag = 0, lflag = 0;
        size_t wordcount = 0;
        const char *optstr = "ls";
        char *longword = NULL, *shortword = NULL;
    
        while ((opt = getopt(argc, argv, optstr)) != -1) {
            switch(opt) {
                case 'l':
                    lflag = 1;
                    break;
                case 's':
                    sflag = 1;
                    break;
                default:
                    fprintf(stderr, "usage: %s [-l] [-s] [filename]n", argv[0]); 
                    exit(EXIT_FAILURE);
            }
        }
    
        /* Checking if file is in directory */
        infile = fopen("myfile.txt", "r");
        if (infile == NULL) {
            fprintf(stderr, "Failed to open filen");
            exit(EXIT_FAILURE);
        }
    
        /* checking if line exists in file */
        if (fgets(line, LINESIZE, infile) == NULL) {
            fprintf(stderr, "No line found in file.n");
    
            printf("nEnter string instead:n");
            if (fgets(line, LINESIZE, stdin) != NULL) {
                remove_newline(line);
                longest_shortest_words(line, &longword, &shortword, &wordcount);   
                /* checking that longWord, shortWord and word_count are valid */
                if (longword != NULL && shortword != NULL && wordcount > 0) {
                    print_output(lflag, sflag, longword, shortword, wordcount);
                }
            }
    
        /* file has line, do stuff with it */
        } else {
            remove_newline(line);
            longest_shortest_words(line, &longword, &shortword, &wordcount);
            print_output(lflag, sflag, longword, shortword, wordcount);
        }
    
        exit(EXIT_SUCCESS);
    }
    
    /* function for printing output, can be improved */
    void print_output(int lflag, int sflag, char *longword, char *shortword, size_t wordcount) {
        if (lflag) {
            printf("Longest word: %sn", longword);
        }
    
        if (sflag) {
            printf("Shortest word: %sn", shortword);
        }
    
        if (wordcount > 0) {
            printf("Word count = %zun", wordcount);
        }
    }
    
    /* function for removing newline, and checking that input hasnt exceeded limit */
    void remove_newline(char line[]) {
        size_t slen;
    
        slen = strlen(line);
        if (slen > 0 && line[slen-1] == 'n') {
            line[slen-1] = '';
        } else {
            fprintf(stderr, "nToo many characters in input.n");
            exit(EXIT_FAILURE);
        }
    }
    
    /* function which parses line, and saves longWord and shortWord in pointers */
    void longest_shortest_words(char line[], char **longword, char **shortword, size_t *wordcount) {
        char *word = NULL;
        const char *delim = " ,.";
    
        word = strtok(line, delim);
        if (word != NULL) {
            *longword = word;
            *shortword = word;
            *wordcount = 1;
        }
    
        while ((word = strtok(NULL, delim)) != NULL) {
            (*wordcount)++;
            if (strlen(word) > strlen(*longword)) {
                *longword = word;
            } else if (strlen(word) < strlen(*shortword)) {
                *shortword = word;
            } 
        }
    }
    

    注意:上面显示的代码可以改进,只是向您展示解决问题的另一种方法。

    链接地址: http://www.djcxy.com/p/43899.html

    上一篇: Segmentation faulting in assignment

    下一篇: What could be the reason for segmentation fault in python bindings