从fgets中删除换行符

时间:2014-09-02 04:34:25

标签: c newline fgets

如果这个问题很明显,或者我犯了一个简单的逻辑错误,我很抱歉。我已经搜索了各种方法来摆脱使用fgets产生的换行符,但是在构建时我仍然遇到问题。我认为我不能正确理解某些内容并错误地应用我的“解决方案”。我希望透明,并说这是学校的任务。一切都运行良好,除了我的输出,它有不必要的新行。

此功能的唯一目的是将名称读入结构数组。

void initialize(FILE * ifp, Candidate * electionCandidates, int count)
{

for (int i = 0; i < count; i++)
{

    fgets (electionCandidates[i].name , 20 , ifp);

    if (electionCandidates[i].name[strlen(electionCandidates[i].name) - 1] == '\n')
    {
        electionCandidates[i].name[strlen(electionCandidates[i].name) - 1] = '\0';
    }   
} 
}

当我尝试运行时显示以下内容:“隐式声明库函数”strlen“类型为unsigned long(常量字符*)”

3 个答案:

答案 0 :(得分:2)

1)不,不一定是“明显的” - 好问题。

2)是的,你想使用“strlen()”。

3)听起来你忘了#include <string.h>来定义“strlen()”。

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

char *trim (char *s) {
  int i = strlen(s)-1;
  if ((i > 0) && (s[i] == '\n'))
    s[i] = '\0';
  return s;
}

答案 1 :(得分:0)

这是我的看法。

#include <stdio.h>
#include <string.h> // to fix the warning
...

// remove NL left by fgets, with protection
void trimnl (char *s) {
  char *pnl = s + strlen(s);
  if (*s && *--pnl == '\n')
    *pnl = 0;
}

void initialize(FILE* ifp, Candidate* electionCandidates, int count) {
for (int i = 0; i < count; i++) {
    fgets (electionCandidates[i].name, 20, ifp);
    trimnl(electionCandidates[i].name);
  } 
}

在我的原始版本中,代码为

  char *pnl = s + strlen(s) - 1;

这是基于带有无符号值的带符号算法的批评。但是,批评不适用,因为在这种情况下,最终结果(如果strlen = 0)等同于:

  char *pnl = s - 1;

没有无符号算术问题,但存在未定义的行为问题。这就是我改变代码的原因。

答案 2 :(得分:0)

将来,使用-Wall进行编译以启用编译警告。

根据您的编译器,您将获得有关如何解决此问题以及类似问题的有用建议(已在本主题其他地方的一个答案中进行了讨论 - 使用Clang进行编译将警告您缺少include,例如)。