c - 段错误,但找不到位置

标签 c csv

我陷入困境,因为我不明白为什么我的解析器代码无法正常工作,编译器只是说段错误。当另一个编译器编译它但它只返回一个错误代码

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

const char *
getfield (char *line, int num)
{
  const char *tok;
  for (tok = strtok (line, ","); tok && *tok; tok = strtok (NULL, ",\n"))
  {
    if (!--num)
      return tok;
  }
  return NULL;
}

int
main ()
{
  FILE *stream = fopen ("input", "r");
  FILE *fp;
  char line[1024];
  while (fgets (line, 1024, stream))
  {
     char *tmp = strdup (line);
     char buf[0x100];
     snprintf (buf, sizeof (buf), "c:\\temp\\%s.txt", getfield (tmp, 1));
     fp = fopen (buf, "w");
     int count = 0;
     while ((tmp = strchr (tmp, ',')) != NULL)
     {
       count++;
       tmp++;
     }
     if (count == 4 ){
       fprintf (fp,
               "{This is my name %s\n I'm %s years old\n my       useragent is %s\n My hobbies are %s\n}",
               getfield (tmp, 1), getfield (tmp, 2),
               getfield (tmp, 4), getfield (tmp, 5));
     }
     else {
        fprintf (fp,
                 "{This is my name %s\n I'm %s years old\n my       useragent is %s%s\n My hobbies are %s\n}",
                 getfield (tmp, 1), getfield (tmp, 2),
                 getfield (tmp, 4), getfield (tmp, 5),
                 getfield (tmp, 6));
     }

     fclose (fp);
     free (tmp);
   }
}

我有一个包含数千行的 csv 文件。示例

Name,age,gender,useragent,hobby
maximilian,16,Male,Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko,skateboard

我正在尝试为每个名称创建一个文件并在其中添加其他信息。所以它会输出这个例如

maximilain.txt

This is my name maximilian
 I'm 16 years old
 my useragent is Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
 My hobbies are skateboard

最佳答案

之后

while ((tmp = strchr (tmp, ',')) != NULL)
{
  count++;
  tmp++;
}

tmp为NULL,因此下次调用getfield将得到一个空指针,while必须在其他指针上完成,或者您需要在<之前保存tmp/p>

例如:

char * p = tmp;

while ((p = strchr (p, ',')) != NULL)
{
  count++;
  p++;
}
<小时/>

正如评论中已经说过的,您使用 strtok 是错误的,因为每次调用后都会修改字符串。

您可以修改getfield以处理副本:

const char *
getfield (char *line, int num)
{
  static char l[1024];
  strcpy(l, line);
  const char *tok;
  for (tok = strtok (l, ","); tok && *tok; tok = strtok (NULL, ",\n"))
  {
    if (!--num)
      return tok;
  }
  return NULL;
}

但这是一个糟糕的方法,因为每次都必须绕过越来越多的标记来抛出字符串。

我让您优化代码,以便在每行上仅提取每个标记一次。

<小时/>

另请注意,您使用了 csv 的第一行,因此您根据“名称”等创建了一个文件

关于c - 段错误,但找不到位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54199550/

相关文章:

csv - 使用 bash 或 awk 打乱大型 csv 文件的行和列

c# - 如何将 CSV 文件批量插入 SQLite C#

c - 在包含三元运算符的表达式中使用括号

c - 贪吃蛇游戏 : Why "(Sometimes, lower than 10%)" the snacks (cookies) are created on the snake body?

c - 如何在隐藏模式下创建GUI进程?

c - dlmalloc 中的 bin_at

python - 基于groupby拆分csv文件数千次

c - 在 C 中,将结构作为参数传递给 printf 的预期行为是什么?

python - 如何使用 django_postgres_copy 将 headless csv 导入 postgresql?

string - 需要格式良好的数据进行测试