问题
I am sorry if this question is obvious, or if I am making a simple logic mistake. I have searched for various ways of getting rid of the newline that comes from using fgets, but I continue running into problems while building. I think I am not understanding something properly and applying my "solution" incorrectly. I would like to be transparent and say that this is an assignment for school. Everything runs well except my output, which has unnecessary new lines.
The sole purpose of this function is to read names into an array of structs.
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';
}
}
}
The following is displayed when I attempt to run: "Implicitly declaring library function "strlen" with type unsigned long (constant char*)"
回答1:
1) No, not necessarily "obvious" - good question.
2) Yes, you want to use "strlen()".
3) It sounds like you forgot #include <string.h>
to defined "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;
}
回答2:
Here is my take.
#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);
}
}
In my original version, the code read
char *pnl = s + strlen(s) - 1;
This was criticised on the basis of signed arithmetic with unsigned values. However, the criticism does not apply because in this case the end result (if strlen = 0) is equivalent to:
char *pnl = s - 1;
There is no unsigned arithmetic problem, but instead there is an Undefined Behaviour problem. That's why I changed the code.
回答3:
In the future, compile with -Wall
to enable compilation warnings.
Depending on your compiler, you'll get useful advice on how to solve this and similar problems (which have been discussed in one answer elsewhere in this thread — compiling with Clang will warn you about the missing include
, for instance).
来源:https://stackoverflow.com/questions/25615916/removing-newline-from-fgets