分配错误在作业

问题描述:

我目前正在学习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 = %.2d\n", count); 

    exit(0); 
} 
+0

你认为传入'main()'的int argc'的目的可能是什么? –

+1

建议您使用调试器。这是正确的工具,你将从学习中受益。 – kaylum

+0

“将我的所有指针初始化为NULL”。尽管你认为你读过,但这不是解决seg故障的方法。 *访问* NULL指针是seg故障的常见原因。这正是你的'string'变量的价值所在。 – kaylum

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

  • 您初始化stringNULL,然后将其作为fgets()输入缓冲器。 fgets()重新提供一个指向字符数组的指针,这些字符可以在堆栈中声明或动态分配为malloc(3)。您可以设置一个输入缓冲区,例如char string[100]
  • fgets()必须检查,因为它无法读取一行时返回NULL
  • strtok()的分隔符不是\n附加fgets()的字符。您可以删除此换行符,也可以将其包含在分隔符中。如果您想将其包含在分隔符中,请确保您的分隔符是" ,.-\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 file\n"); 
        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] = {'\0'}; 
    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 file\n"); 
     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: %s\n", longword); 
    } 

    if (sflag) { 
     printf("Shortest word: %s\n", shortword); 
    } 

    if (wordcount > 0) { 
     printf("Word count = %zu\n", 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] = '\0'; 
    } 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; 
     } 
    } 
} 

注:上面显示的代码可以改善,它只是告诉你另一种方法,您的问题。