使用strtok()和fgets()会导致段错误,但指针应该是正确的

时间:2011-12-03 22:27:04

标签: c file-io fgets strtok

我对C很陌生,并且认为我还要多学习一点。我试图编写一些代码来读取预先存在的文本文件并格式化并将其写入磁盘。当它编译时,每当我不确定我应该得到一个时,我会得到一个段错误。我浏览了大部分手册页,找不到任何有用的内容。

以下是代码:

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

int main()
{
   FILE *file = fopen("listing.txt","r"), *output;

   char *fvar;
   char *svar;
   char delim[] = ",";
   int num;
   char ch;
   char line[66];
   int listnum = 0;

   if(file == NULL){
        printf("Cannot open file.\n");
        exit(1);
   }

   output = fopen("report.txt","w");

   fprintf(output, "%s", "First Name     Last Name     Number ");
   fprintf(output, "%s", "-------------------------------------");

   while(fgets(line, 66, file) != NULL){
       ch = line[0];
       if((ch >= 'a') && (ch <= 'z')){
           fvar = strtok(line,delim);
           svar = strtok(NULL,delim);
           listnum++;
       }
       else {
            num = atoi(line);
       }
       fprintf(output, "%s", fvar);
       fprintf(output, "%15s", svar);
       fprintf(output, "%30d", num);
       fprintf(output, "%56s", "\n");
   }
   fclose(file); /* done reading from the input file */
   fclose(output); /* done writing the the output file */
   return 0;
}

我尝试做的是读取文本文件的一行。如果该行包含信息的方式&#34;字符串,字符串&#34;然后将这两个标记化并分别存储在fvar和svar中。如果是数字字符串,请使用atoi()获取值并将其存储在num。

出于某种原因,这会导致段错误,但编译得很好。我非常确定问题出在fvar = strtok(temp,delim);svar = strtok(NULL,delim);行,但我不知道如何修改它。注意:如果我使用fvar = strtok(line,delim);,则会出现相同的行为。

编辑:已修复,谢谢@Chris Dodd。按照我自己的意愿,我会去取一年级的教科书并再次学习我的字母表。

2 个答案:

答案 0 :(得分:2)

最有可能的问题是你的第一个输入行不是以小写字母开头,所以你从不首先调用strtok,也从不分配给svar或fvar,但你仍然传递那些(未初始化的)值printf,然后给出一个段错误...

尝试使用调试器单步执行代码以查看其实际位置。

答案 1 :(得分:0)

strtok可以返回NULL。如果忽略这种可能性,很容易导致访问冲突。始终检查您呼叫的功能的返回状态。

fvar = strtok(temp, delim); 
if (fvar != NULL) 
{
    printf("%s\n", fvar);
    svar = strtok(NULL, delim);
    if (svar != NULL)
    {
        printf("%s\n", svar);
    }
    else
    {
        /* illegal to access contents of svar */
    } 
 } 
 else 
 {
     /* illegal to access contents of fvar */ 
 }

/ *     与问题无关,你可能会发现包含文件ctype.h很有用,因为它提供了     形式的一系列功能.... toupper,isletter,isdigit等等 * /