读取一行,标记并分配给C中的struct

时间:2010-12-21 19:49:38

标签: c string

line是fgets'd,并且在带有计数器while的{​​{1}}循环中运行,n是一个包含2个char数组的结构dp。基本上,简而言之,我想读一行,将它分成2个字符串,一个直到第一个空格,另一个直到第一个空格。我事后清理(q从文件变成''0')。代码有效,但是有更惯用的方法吗?我在“不知不觉中”遇到了什么错误?

\n

编辑 size_t spc = strcspn(line," "); strncpy(d[n].p, line, spc); d[n].p[spc+1]='\0'; size_t l = strlen(line)-spc; strncpy(d[n].q, line+spc+1, l); char* nl = strchr(d[n].q, '\n'); if(nl){ *nl='\0'; } n++; 可能包含空格。

感谢。

4 个答案:

答案 0 :(得分:2)

这可以仅使用纯指针算法完成。假设line包含当前行:

char *p = line;
char *part1, *part2;

while (*p && *p != ' ') {
  p++;
}

if (*p == ' ') {
  *p++ = '\0';
  part1 = strdup(line);
  part2 = strdup(p);

  if (!part1 || !part2) {
    /* insufficient memory */
  }
} else {
  /* line doesn't contain a space */
}

基本上你扫描字符串直到第一次出现空格,然后用空字符替换空格以指示第一部分的结尾(strdup需要知道停止的位置),并推进指针用一个来得到其余的字符串。

为了使代码看起来更干净但是由于调用函数的开销,您可以使用strchr()而不是while循环:

char *p = strchr(line, ' ');
char *part1, *part2;

if (p) {
  *p++ = '\0';
  part1 = strdup(line);
  part2 = strdup(p);
}

答案 1 :(得分:1)

您可以随时使用:

sscanf(line, "%s %s", d[n].p, d[n].q);

假设你要放入p和q的东西不包含空格,并且p和q保证足够大以容纳包括零终止的标记。

scanf功能很危险,但在正确使用时非常有用。

答案 2 :(得分:1)

scanf("%s %[^\n]", d[n].p, d[n].q);

%[...]指令与%s类似,但不是匹配非空格,而是匹配括号内的字符 - 或除括号中的字符外的所有字符,如果^是领先。

您应该检查返回值以查看是否实际输入了q;如果“其余行”实际上是空的,那么这与您的代码有一些不同的行为。 (或者如果该行以空格开头。)

答案 3 :(得分:1)

我会写几乎你所拥有的代码。一些调整:

  • 您在strncpy处未获得任何内容,请使用memcpy
  • 您也没有从strcspn获得任何内容,请使用strchr
  • 避免两次扫描部分字符串。

所以:

char *spc = strchr(line, ' ');
memcpy(d[n].p, line, spc - line);
d[n].p[spc - line] = '\0';

spc++;
char *end = strchr(spc, '\n');
if (end)
{
    memcpy(d[n].q, spc, end - spc);
    d[n].q[end - spc] = '\0';
} 
else 
    strcpy(d[n].q, spc);

n++;